r600g: fix draw-elements and draw-elements-base-vertex
[mesa.git] / src / gallium / drivers / r600 / r600_state.c
index 5d6236206f78b9d927b13ea404999defcaf993b9..424f7a8913f805ef02c00285254fd15fe4b11deb 100644 (file)
 #include "r600_context.h"
 #include "r600_resource.h"
 
+static void clean_flush(struct r600_context *rctx, struct radeon_state *flush);
+static int setup_cb_flush(struct r600_context *rctx, struct radeon_state *flush);
+static int setup_db_flush(struct r600_context *rctx, struct radeon_state *flush);
+
 static struct r600_context_state *r600_new_context_state(unsigned type)
 {
        struct r600_context_state *rstate = CALLOC_STRUCT(r600_context_state);
@@ -378,6 +382,14 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        struct r600_context_state *rstate;
        int i;
 
+       if (rctx->framebuffer) {
+               for (i = 0; i < rctx->framebuffer->state.framebuffer.nr_cbufs; i++)
+                       radeon_draw_unbind(&rctx->draw, &rctx->framebuffer->rstate[i+1]);
+               radeon_draw_unbind(&rctx->draw, &rctx->framebuffer->rstate[0]);
+       }
+       clean_flush(rctx, &rctx->hw_states.cb_flush);
+       clean_flush(rctx, &rctx->hw_states.db_flush);
+
        r600_context_state_decref(rctx->framebuffer);
 
        rstate = r600_new_context_state(pipe_framebuffer_type);
@@ -393,6 +405,10 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        if (state->zsbuf) {
                rctx->vtbl->db(rctx, &rstate->rstate[0], state);
        }
+       /* setup flush states */
+       setup_cb_flush(rctx, &rctx->hw_states.cb_flush);
+       setup_db_flush(rctx, &rctx->hw_states.db_flush);
+
        return;
 }
 
@@ -437,6 +453,7 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx,
 {
        struct r600_context *rctx = r600_context(ctx);
        unsigned i;
+       boolean any_user_buffers = FALSE;
 
        for (i = 0; i < rctx->nvertex_buffer; i++) {
                pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL);
@@ -444,8 +461,11 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx,
        memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
        for (i = 0; i < count; i++) {
                rctx->vertex_buffer[i].buffer = NULL;
+               if (r600_buffer_is_user_buffer(buffers[i].buffer))
+                       any_user_buffers = TRUE;
                pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer);
        }
+       rctx->any_user_vbs = any_user_buffers;
        rctx->nvertex_buffer = count;
 }
 
@@ -507,7 +527,7 @@ void r600_init_state_functions(struct r600_context *rctx)
        rctx->context.set_blend_color = r600_set_blend_color;
        rctx->context.set_clip_state = r600_set_clip_state;
 
-       if (rctx->screen->chip_class == EVERGREEN)
+       if (radeon_get_family_class(rctx->rw) == EVERGREEN)
                rctx->context.set_constant_buffer = eg_set_constant_buffer;
        else if (rctx->screen->use_mem_constant)
                rctx->context.set_constant_buffer = r600_set_constant_buffer_mem;
@@ -550,6 +570,7 @@ struct r600_context_state *r600_context_state_decref(struct r600_context_state *
        case pipe_framebuffer_type:
                for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) {
                        pipe_surface_reference(&rstate->state.framebuffer.cbufs[i], NULL);
+                       radeon_state_fini(&rstate->rstate[i+1]);
                }
                pipe_surface_reference(&rstate->state.framebuffer.zsbuf, NULL);
                break;
@@ -596,6 +617,17 @@ static void r600_bind_shader_sampler(struct r600_context *rctx, struct r600_shad
        }
 }
 
+static void clean_flush(struct r600_context *rctx, struct radeon_state *flush)
+{
+       struct r600_screen *rscreen = rctx->screen;
+       int i;
+
+       for (i = 0 ; i < flush->nbo; i++) {
+               radeon_ws_bo_reference(rscreen->rw, &flush->bo[i], NULL);
+       }
+       flush->nbo = 0;
+       radeon_state_fini(flush);
+}
 
 static int setup_cb_flush(struct r600_context *rctx, struct radeon_state *flush)
 {
@@ -654,10 +686,6 @@ int r600_context_hw_states(struct pipe_context *ctx)
        rctx->vtbl->dsa(rctx, &rctx->hw_states.dsa);
        rctx->vtbl->cb_cntl(rctx, &rctx->hw_states.cb_cntl);
                                                               
-       /* setup flushes */
-       setup_db_flush(rctx, &rctx->hw_states.db_flush);
-       setup_cb_flush(rctx, &rctx->hw_states.cb_flush);
-
        /* bind states */
        radeon_draw_bind(&rctx->draw, &rctx->config);
 
@@ -669,9 +697,6 @@ int r600_context_hw_states(struct pipe_context *ctx)
        radeon_draw_bind(&rctx->draw, &rctx->hw_states.db_flush);
        radeon_draw_bind(&rctx->draw, &rctx->hw_states.cb_flush);
 
-       radeon_draw_bind(&rctx->draw, &rctx->hw_states.db_flush);
-       radeon_draw_bind(&rctx->draw, &rctx->hw_states.cb_flush);
-
        if (rctx->viewport) {
                radeon_draw_bind(&rctx->draw, &rctx->viewport->rstate[0]);
        }