r600g: split pipe state creating/binding from hw state creation
authorJerome Glisse <jglisse@redhat.com>
Wed, 28 Jul 2010 23:33:50 +0000 (19:33 -0400)
committerJerome Glisse <jglisse@redhat.com>
Wed, 28 Jul 2010 23:36:16 +0000 (19:36 -0400)
Split hw vs pipe states creation handling as hw states group doesn't
match pipe state group exactly. Right now be dumb about that and
rebuild all hw states on each draw call. More optimization on that
side coming.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_buffer.c
src/gallium/drivers/r600/r600_context.c
src/gallium/drivers/r600/r600_context.h
src/gallium/drivers/r600/r600_draw.c
src/gallium/drivers/r600/r600_resource.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_state.c
src/gallium/winsys/r600/drm/r600_drm.c

index 1dcb19babc96ba80c82fab21d56de88e2749b390..cc37227eada2ac84b809f2b6e6d51911330b61df 100644 (file)
 
 static void r600_blitter_save_states(struct r600_context *rctx)
 {
-       util_blitter_save_blend(rctx->blitter,
-                                       rctx->draw->state[R600_BLEND]);
-       util_blitter_save_depth_stencil_alpha(rctx->blitter,
-                                       rctx->draw->state[R600_DSA]);
-       util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref);
-       util_blitter_save_rasterizer(rctx->blitter,
-                                       rctx->draw->state[R600_RASTERIZER]);
-       util_blitter_save_fragment_shader(rctx->blitter,
-                                       rctx->ps_shader);
-       util_blitter_save_vertex_shader(rctx->blitter,
-                                       rctx->vs_shader);
-       util_blitter_save_vertex_elements(rctx->blitter,
-                                       rctx->vertex_elements);
-       util_blitter_save_viewport(rctx->blitter,
-                                       &rctx->viewport);
+       util_blitter_save_blend(rctx->blitter, rctx->blend);
+       util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa);
+       if (rctx->stencil_ref) {
+               util_blitter_save_stencil_ref(rctx->blitter,
+                                       &rctx->stencil_ref->state.stencil_ref);
+       }
+       util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer);
+       util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
+       util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
+       util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements);
+       if (rctx->viewport) {
+               util_blitter_save_viewport(rctx->blitter, &rctx->viewport->state.viewport);
+       }
        /* XXX util_blitter_save_clip(rctx->blitter, &rctx->clip); */
        util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer,
-                                        rctx->vertex_buffer);
+                                       rctx->vertex_buffer);
+
+       /* remove ptr so they don't get deleted */
+       rctx->blend = NULL;
+       rctx->vs_shader = NULL;
+       rctx->ps_shader = NULL;
+       rctx->rasterizer = NULL;
+       rctx->dsa = NULL;
+       rctx->vertex_elements = NULL;
 }
 
 static void r600_clear(struct pipe_context *ctx, unsigned buffers,
                       const float *rgba, double depth, unsigned stencil)
 {
        struct r600_context *rctx = r600_context(ctx);
-       struct pipe_framebuffer_state *fb = &rctx->fb_state;
+       struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
 
        r600_blitter_save_states(rctx);
        util_blitter_clear(rctx->blitter, fb->width, fb->height,
@@ -73,12 +79,14 @@ static void r600_clear_render_target(struct pipe_context *pipe,
                                     unsigned width, unsigned height)
 {
        struct r600_context *rctx = r600_context(pipe);
+       struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
 
        r600_blitter_save_states(rctx);
-       util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state);
+       util_blitter_save_framebuffer(rctx->blitter, fb);
 
        util_blitter_clear_render_target(rctx->blitter, dst, rgba,
                                         dstx, dsty, width, height);
+R600_ERR("vtx elem %p\n", rctx->vertex_elements);
 }
 
 static void r600_clear_depth_stencil(struct pipe_context *pipe,
@@ -90,12 +98,14 @@ static void r600_clear_depth_stencil(struct pipe_context *pipe,
                                     unsigned width, unsigned height)
 {
        struct r600_context *rctx = r600_context(pipe);
+       struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
 
        r600_blitter_save_states(rctx);
-       util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state);
+       util_blitter_save_framebuffer(rctx->blitter, fb);
 
        util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil,
                                         dstx, dsty, width, height);
+R600_ERR("vtx elem %p\n", rctx->vertex_elements);
 }
 
 static void r600_resource_copy_region(struct pipe_context *pipe,
index 167d11752011d2376e7ddd73cf071f7f65d7a223..7829a479c2e0b07015f5b06d368ae5457a1b73de 100644 (file)
@@ -141,6 +141,7 @@ static void r600_buffer_destroy(struct pipe_screen *screen,
        if (rbuffer->bo) {
                radeon_bo_decref(rscreen->rw, rbuffer->bo);
        }
+       memset(rbuffer, 0, sizeof(struct r600_resource));
        FREE(rbuffer);
 }
 
index f2875f4380044f304bc8edf1d4853df39736abc5..4c7b67ea52c8e0d7cd52cda3e1da334edf56222c 100644 (file)
@@ -220,9 +220,9 @@ static void r600_init_config(struct r600_context *rctx)
        printf("num_gs_stack_entries : %d\n", num_gs_stack_entries);
        printf("num_es_stack_entries : %d\n", num_es_stack_entries);
 
-       rctx->config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG);
+       rctx->hw_states.config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG);
 
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000;
        switch (family) {
        case CHIP_RV610:
        case CHIP_RV620:
@@ -231,75 +231,75 @@ static void r600_init_config(struct r600_context *rctx)
        case CHIP_RV710:
                break;
        default:
-               rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1);
+               rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1);
                break;
        }
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1);
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1);
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio);
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio);
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio);
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio);
 
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0;
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs);
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs);
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs);
 
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0;
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs);
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs);
 
-       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0;
-       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads);
-       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads);
-       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads);
-       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads);
 
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0;
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries);
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries);
 
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0;
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries);
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries);
 
-       rctx->config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000;
-       rctx->config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002;
-       rctx->config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__DB_DEBUG] = 0x00000000;
-       rctx->config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204;
-       rctx->config->states[R600_CONFIG__SX_MISC] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001;
-       rctx->config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003;
-       rctx->config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000;
-       rctx->config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001;
-       rctx->config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000;
-       radeon_state_pm4(rctx->config);
+       rctx->hw_states.config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000;
+       rctx->hw_states.config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002;
+       rctx->hw_states.config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__DB_DEBUG] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204;
+       rctx->hw_states.config->states[R600_CONFIG__SX_MISC] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001;
+       rctx->hw_states.config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000;
+       rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000;
+       radeon_state_pm4(rctx->hw_states.config);
 }
 
 struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
@@ -333,19 +333,19 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
                return NULL;
        }
 
-       rctx->cb_cntl = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL);
-       rctx->cb_cntl->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F;
-       rctx->cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F;
-       rctx->cb_cntl->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0000;
-       rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000;
-       rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000;
-       rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000;
-       rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
-       rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000;
-       rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
-       rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
-       rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
-       radeon_state_pm4(rctx->cb_cntl);
+       rctx->hw_states.cb_cntl = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL);
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0000;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
+       rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
+       radeon_state_pm4(rctx->hw_states.cb_cntl);
 
        r600_init_config(rctx);
 
index 30f33f757ec03dd16fca2f9eb9e680ba91eaeb4c..1f03b202eecdc6d7ff3e83069f965b8751771286 100644 (file)
 #include "r600_shader.h"
 
 /* XXX move this to a more appropriate place */
-struct r600_vertex_elements_state
-{
-       unsigned count;
-       struct pipe_vertex_element elements[32];
+union pipe_states {
+       struct pipe_rasterizer_state            rasterizer;
+       struct pipe_poly_stipple                poly_stipple;
+       struct pipe_scissor_state               scissor;
+       struct pipe_clip_state                  clip;
+       struct pipe_shader_state                shader;
+       struct pipe_depth_state                 depth;
+       struct pipe_stencil_state               stencil;
+       struct pipe_alpha_state                 alpha;
+       struct pipe_depth_stencil_alpha_state   dsa;
+       struct pipe_blend_state                 blend;
+       struct pipe_blend_color                 blend_color;
+       struct pipe_stencil_ref                 stencil_ref;
+       struct pipe_framebuffer_state           framebuffer;
+       struct pipe_sampler_state               sampler;
+       struct pipe_sampler_view                sampler_view;
+       struct pipe_viewport_state              viewport;
 };
 
-struct r600_pipe_shader {
-       struct r600_shader                      shader;
-       struct radeon_bo                        *bo;
-       struct radeon_state                     *state;
+enum pipe_state_type {
+       pipe_rasterizer_type = 1,
+       pipe_poly_stipple_type,
+       pipe_scissor_type,
+       pipe_clip_type,
+       pipe_shader_type,
+       pipe_depth_type,
+       pipe_stencil_type,
+       pipe_alpha_type,
+       pipe_dsa_type,
+       pipe_blend_type,
+       pipe_stencil_ref_type,
+       pipe_framebuffer_type,
+       pipe_sampler_type,
+       pipe_sampler_view_type,
+       pipe_viewport_type,
+       pipe_type_count
 };
 
-struct r600_texture_resource {
-       struct pipe_sampler_view                view;
-       struct radeon_state                     *state;
+struct r600_context_state {
+       union pipe_states               state;
+       unsigned                        refcount;
+       unsigned                        type;
+       struct radeon_state             *rstate;
+       struct r600_shader              shader;
+       struct radeon_bo                *bo;
+};
+
+struct r600_vertex_element
+{
+       unsigned                        refcount;
+       unsigned                        count;
+       struct pipe_vertex_element      elements[32];
+};
+
+struct r600_context_hw_states {
+       struct radeon_state     *rasterizer;
+       struct radeon_state     *scissor;
+       struct radeon_state     *dsa;
+       struct radeon_state     *blend;
+       struct radeon_state     *viewport;
+       struct radeon_state     *cb0;
+       struct radeon_state     *config;
+       struct radeon_state     *cb_cntl;
+       struct radeon_state     *db;
+       unsigned                ps_nresource;
+       unsigned                ps_nsampler;
+       struct radeon_state     *ps_resource[160];
+       struct radeon_state     *ps_sampler[16];
 };
 
 struct r600_context {
@@ -56,9 +109,11 @@ struct r600_context {
        struct r600_screen              *screen;
        struct radeon                   *rw;
        struct radeon_ctx               *ctx;
-       struct radeon_state             *cb_cntl;
-       struct radeon_state             *db;
-       struct radeon_state             *config;
+       struct blitter_context          *blitter;
+       struct radeon_draw              *draw;
+       /* hw states */
+       struct r600_context_hw_states   hw_states;
+#if 0
        struct r600_pipe_shader         *ps_shader;
        struct r600_pipe_shader         *vs_shader;
        unsigned                        nps_sampler;
@@ -71,12 +126,57 @@ struct r600_context {
        unsigned                        nvertex_buffer;
        struct r600_vertex_elements_state *vertex_elements;
        struct pipe_vertex_buffer       vertex_buffer[PIPE_MAX_ATTRIBS];
-       struct blitter_context          *blitter;
        struct pipe_stencil_ref         stencil_ref;
        struct pipe_framebuffer_state   fb_state;
-       struct radeon_draw              *draw;
        struct pipe_viewport_state      viewport;
+#endif
+       /* pipe states */
+       unsigned                        flat_shade;
+       unsigned                        ps_nsampler;
+       unsigned                        vs_nsampler;
+       unsigned                        ps_nsampler_view;
+       unsigned                        vs_nsampler_view;
+       unsigned                        nvertex_buffer;
+       struct r600_context_state       *rasterizer;
+       struct r600_context_state       *poly_stipple;
+       struct r600_context_state       *scissor;
+       struct r600_context_state       *clip;
+       struct r600_context_state       *ps_shader;
+       struct r600_context_state       *vs_shader;
+       struct r600_context_state       *depth;
+       struct r600_context_state       *stencil;
+       struct r600_context_state       *alpha;
+       struct r600_context_state       *dsa;
+       struct r600_context_state       *blend;
+       struct r600_context_state       *stencil_ref;
+       struct r600_context_state       *viewport;
+       struct r600_context_state       *framebuffer;
+       struct r600_context_state       *ps_sampler[PIPE_MAX_ATTRIBS];
+       struct r600_context_state       *vs_sampler[PIPE_MAX_ATTRIBS];
+       struct r600_context_state       *ps_sampler_view[PIPE_MAX_ATTRIBS];
+       struct r600_context_state       *vs_sampler_view[PIPE_MAX_ATTRIBS];
+       struct r600_vertex_element      *vertex_elements;
+       struct pipe_vertex_buffer       vertex_buffer[PIPE_MAX_ATTRIBS];
+};
+
+#if 0
+struct r600_vertex_elements_state
+{
+       unsigned count;
+       struct pipe_vertex_element      elements[32];
+};
+
+struct r600_pipe_shader {
+       struct r600_shader              shader;
+       struct radeon_bo                *bo;
+       struct radeon_state             *state;
+};
+
+struct r600_texture_resource {
+       struct pipe_sampler_view        view;
+       struct radeon_state             *state;
 };
+#endif
 
 /* Convenience cast wrapper. */
 static INLINE struct r600_context *r600_context(struct pipe_context *pipe)
@@ -84,6 +184,12 @@ static INLINE struct r600_context *r600_context(struct pipe_context *pipe)
     return (struct r600_context*)pipe;
 }
 
+struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state);
+struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate);
+struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate);
+
+int r600_context_hw_states(struct r600_context *rctx);
+
 void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
                        unsigned start, unsigned count);
 void r600_draw_elements(struct pipe_context *ctx,
@@ -101,10 +207,11 @@ void r600_init_state_functions(struct r600_context *rctx);
 void r600_init_query_functions(struct r600_context* rctx);
 struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv);
 
-void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
-struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx,
-                                               const struct tgsi_token *tokens);
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
+int r600_pipe_shader_create(struct pipe_context *ctx,
+                       struct r600_context_state *rstate,
+                       const struct tgsi_token *tokens);
+int r600_pipe_shader_update(struct pipe_context *ctx,
+                               struct r600_context_state *rstate);
 
 #define R600_ERR(fmt, args...) \
        fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args)
index 8e9d11b8550da0014e456bb0ec9528e8f63945d6..b248beaf8c69ea9302bca5e2ca87c353857153e7 100644 (file)
@@ -55,8 +55,12 @@ static int r600_draw_common(struct r600_draw *draw)
        struct r600_resource *rbuffer;
        unsigned i, j, offset, format, prim;
        u32 vgt_dma_index_type, vgt_draw_initiator;
+       struct pipe_vertex_buffer *vertex_buffer;
        int r;
 
+       r = r600_context_hw_states(rctx);
+       if (r)
+               return r;
        switch (draw->index_size) {
        case 2:
                vgt_draw_initiator = 0;
@@ -84,26 +88,18 @@ static int r600_draw_common(struct r600_draw *draw)
        r = r600_pipe_shader_update(draw->ctx, rctx->ps_shader);
        if (r)
                return r;
-       r = radeon_draw_set(rctx->draw, rctx->vs_shader->state);
-       if (r)
-               return r;
-       r = radeon_draw_set(rctx->draw, rctx->ps_shader->state);
-       if (r)
-               return r;
-       r = radeon_draw_set(rctx->draw, rctx->cb_cntl);
-       if (r)
-               return r;
-       r = radeon_draw_set(rctx->draw, rctx->db);
+       r = radeon_draw_set(rctx->draw, rctx->vs_shader->rstate);
        if (r)
                return r;
-       r = radeon_draw_set(rctx->draw, rctx->config);
+       r = radeon_draw_set(rctx->draw, rctx->ps_shader->rstate);
        if (r)
                return r;
 
        for (i = 0 ; i < rctx->vertex_elements->count; i++) {
                j = rctx->vertex_elements->elements[i].vertex_buffer_index;
-               rbuffer = (struct r600_resource*)rctx->vertex_buffer[j].buffer;
-               offset = rctx->vertex_elements->elements[i].src_offset + rctx->vertex_buffer[j].buffer_offset;
+               vertex_buffer = &rctx->vertex_buffer[j];
+               rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+               offset = rctx->vertex_elements->elements[i].src_offset + vertex_buffer->buffer_offset;
                r = r600_conv_pipe_format(rctx->vertex_elements->elements[i].src_format, &format);
                if (r)
                        return r;
@@ -114,7 +110,7 @@ static int r600_draw_common(struct r600_draw *draw)
                vs_resource->nbo = 1;
                vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset;
                vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset;
-               vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(rctx->vertex_buffer[j].stride) |
+               vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(vertex_buffer->stride) |
                                                                S_038008_DATA_FORMAT(format);
                vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000;
                vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000;
@@ -126,17 +122,19 @@ static int r600_draw_common(struct r600_draw *draw)
                if (r)
                        return r;
        }
+#if 0
        /* setup texture sampler & resource */
-       for (i = 0 ; i < rctx->nps_sampler; i++) {
-               r = radeon_draw_set_new(rctx->draw, rctx->ps_sampler[i]);
+       for (i = 0 ; i < rctx->ps_nsampler; i++) {
+               r = radeon_draw_set_new(rctx->draw, rctx->ps_sampler[i]->rstate);
                if (r)
                        return r;
        }
-       for (i = 0 ; i < rctx->nps_view; i++) {
-               r = radeon_draw_set_new(rctx->draw, rctx->ps_view[i]->state);
+       for (i = 0 ; i < rctx->ps_nsampler_view; i++) {
+               r = radeon_draw_set_new(rctx->draw, rctx->ps_sampler_view[i]->rstate);
                if (r)
                        return r;
        }
+#endif
        /* FIXME start need to change winsys */
        draw->draw = radeon_state(rscreen->rw, R600_DRAW_TYPE, R600_DRAW);
        if (draw->draw == NULL)
index 292c5d294d8cd8f4ed1c6d82ddd01a9abb61ab02..8dc411ef40934ab353dfcbff3409f26357e23beb 100644 (file)
@@ -24,7 +24,6 @@
 #include "r600_context.h"
 #include "r600_resource.h"
 #include "r600_screen.h"
-#include "r600_texture.h"
 
 static struct pipe_resource *r600_resource_create(struct pipe_screen *screen,
                                                const struct pipe_resource *templ)
index 3909c704e76d7b4aba30a6a2062786e4cff48498..8837a7272b57e70f8382a50cd2984966896eefbc 100644 (file)
@@ -98,43 +98,40 @@ static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shad
        return r600_bc_build(&shader->bc);
 }
 
-struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx,
-                                               const struct tgsi_token *tokens)
+int r600_pipe_shader_create(struct pipe_context *ctx,
+                       struct r600_context_state *rpshader,
+                       const struct tgsi_token *tokens)
 {
        struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
        int r;
 
 fprintf(stderr, "--------------------------------------------------------------\n");
 tgsi_dump(tokens, 0);
        if (rpshader == NULL)
-               return NULL;
+               return -ENOMEM;
        rpshader->shader.family = radeon_get_family(rscreen->rw);
        r = r600_shader_from_tgsi(tokens, &rpshader->shader);
        if (r) {
                R600_ERR("translation from TGSI failed !\n");
-               goto out_err;
+               return r;
        }
        r = r600_bc_build(&rpshader->shader.bc);
        if (r) {
                R600_ERR("building bytecode failed !\n");
-               goto out_err;
+               return r;
        }
 fprintf(stderr, "______________________________________________________________\n");
-       return rpshader;
-out_err:
-       free(rpshader);
-       return NULL;
+       return 0;
 }
 
-static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_state *rpshader)
 {
        struct r600_screen *rscreen = r600_screen(ctx->screen);
        struct r600_shader *rshader = &rpshader->shader;
        struct radeon_state *state;
        unsigned i, j, tmp;
 
-       rpshader->state = radeon_state_decref(rpshader->state);
+       rpshader->rstate = radeon_state_decref(rpshader->rstate);
        state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
        if (state == NULL)
                return -ENOMEM;
@@ -150,22 +147,22 @@ static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader
        }
        state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2);
        state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr);
-       rpshader->state = state;
-       rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
-       rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
-       rpshader->state->nbo = 2;
-       rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
+       rpshader->rstate = state;
+       rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+       rpshader->rstate->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+       rpshader->rstate->nbo = 2;
+       rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
        return radeon_state_pm4(state);
 }
 
-static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_state *rpshader)
 {
        struct r600_screen *rscreen = r600_screen(ctx->screen);
        struct r600_shader *rshader = &rpshader->shader;
        struct radeon_state *state;
        unsigned i, tmp;
 
-       rpshader->state = radeon_state_decref(rpshader->state);
+       rpshader->rstate = radeon_state_decref(rpshader->rstate);
        state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
        if (state == NULL)
                return -ENOMEM;
@@ -180,14 +177,14 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
        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;
-       rpshader->state = state;
-       rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
-       rpshader->state->nbo = 1;
-       rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
+       rpshader->rstate = state;
+       rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+       rpshader->rstate->nbo = 1;
+       rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
        return radeon_state_pm4(state);
 }
 
-static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int r600_pipe_shader(struct pipe_context *ctx, struct r600_context_state *rpshader)
 {
        struct r600_screen *rscreen = r600_screen(ctx->screen);
        struct r600_context *rctx = r600_context(ctx);
@@ -221,7 +218,7 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r
        return r;
 }
 
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_context_state *rpshader)
 {
        struct r600_context *rctx = r600_context(ctx);
        int r;
index 7d67e28c063b6fa827d9bc34ada2a050fc007421..0f1e1cd7610e5001f2f662f6c42fe0ff443fcca6 100644 (file)
 #include "r600_resource.h"
 #include "r600d.h"
 
+static void *r600_create_blend_state(struct pipe_context *ctx,
+                                       const struct pipe_blend_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+
+       return r600_context_state(rctx, pipe_blend_type, state);
+}
+
+static void *r600_create_dsa_state(struct pipe_context *ctx,
+                                       const struct pipe_depth_stencil_alpha_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+
+       return r600_context_state(rctx, pipe_dsa_type, state);
+}
+
+static void *r600_create_rs_state(struct pipe_context *ctx,
+                                       const struct pipe_rasterizer_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+
+       return r600_context_state(rctx, pipe_rasterizer_type, state);
+}
+
+static void *r600_create_sampler_state(struct pipe_context *ctx,
+                                       const struct pipe_sampler_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+
+       return r600_context_state(rctx, pipe_sampler_type, state);
+}
+
+static void r600_sampler_view_destroy(struct pipe_context *ctx,
+                                     struct pipe_sampler_view *state)
+{
+       struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+       r600_context_state_decref(rstate);
+}
+
+static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx,
+                                                       struct pipe_resource *texture,
+                                                       const struct pipe_sampler_view *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+
+       rstate = r600_context_state(rctx, pipe_sampler_type, state);
+       pipe_reference(NULL, &texture->reference);
+       rstate->state.sampler_view.texture = texture;
+       rstate->state.sampler_view.reference.count = 1;
+       return &rstate->state.sampler_view;
+}
+
+static void *r600_create_shader_state(struct pipe_context *ctx,
+                                       const struct pipe_shader_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+
+       return r600_context_state(rctx, pipe_shader_type, state);
+}
+
+static void *r600_create_vertex_elements(struct pipe_context *ctx,
+                               unsigned count,
+                               const struct pipe_vertex_element *elements)
+{
+       struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
+
+       assert(count < 32);
+       v->count = count;
+       memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
+       v->refcount = 1;
+       return v;
+}
+
+static void r600_bind_state(struct pipe_context *ctx, void *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+       if (state == NULL)
+               return;
+       switch (rstate->type) {
+       case pipe_rasterizer_type:
+               rctx->rasterizer = r600_context_state_decref(rctx->rasterizer);
+               rctx->rasterizer = r600_context_state_incref(rstate);
+               break;
+       case pipe_poly_stipple_type:
+               rctx->poly_stipple = r600_context_state_decref(rctx->poly_stipple);
+               rctx->poly_stipple = r600_context_state_incref(rstate);
+               break;
+       case pipe_scissor_type:
+               rctx->scissor = r600_context_state_decref(rctx->scissor);
+               rctx->scissor = r600_context_state_incref(rstate);
+               break;
+       case pipe_clip_type:
+               rctx->clip = r600_context_state_decref(rctx->clip);
+               rctx->clip = r600_context_state_incref(rstate);
+               break;
+       case pipe_depth_type:
+               rctx->depth = r600_context_state_decref(rctx->depth);
+               rctx->depth = r600_context_state_incref(rstate);
+               break;
+       case pipe_stencil_type:
+               rctx->stencil = r600_context_state_decref(rctx->stencil);
+               rctx->stencil = r600_context_state_incref(rstate);
+               break;
+       case pipe_alpha_type:
+               rctx->alpha = r600_context_state_decref(rctx->alpha);
+               rctx->alpha = r600_context_state_incref(rstate);
+               break;
+       case pipe_dsa_type:
+               rctx->dsa = r600_context_state_decref(rctx->dsa);
+               rctx->dsa = r600_context_state_incref(rstate);
+               break;
+       case pipe_blend_type:
+               rctx->blend = r600_context_state_decref(rctx->blend);
+               rctx->blend = r600_context_state_incref(rstate);
+               break;
+       case pipe_framebuffer_type:
+               rctx->framebuffer = r600_context_state_decref(rctx->framebuffer);
+               rctx->framebuffer = r600_context_state_incref(rstate);
+               break;
+       case pipe_stencil_ref_type:
+               rctx->stencil_ref = r600_context_state_decref(rctx->stencil_ref);
+               rctx->stencil_ref = r600_context_state_incref(rstate);
+               break;
+       case pipe_viewport_type:
+               rctx->viewport = r600_context_state_decref(rctx->viewport);
+               rctx->viewport = r600_context_state_incref(rstate);
+               break;
+       case pipe_shader_type:
+       case pipe_sampler_type:
+       case pipe_sampler_view_type:
+       default:
+               R600_ERR("invalid type %d\n", rstate->type);
+               return;
+       }
+}
+
+static void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+       rctx->ps_shader = r600_context_state_decref(rctx->ps_shader);
+       rctx->ps_shader = r600_context_state_incref(rstate);
+}
+
+static void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate = (struct r600_context_state *)state;
+
+       rctx->vs_shader = r600_context_state_decref(rctx->vs_shader);
+       rctx->vs_shader = r600_context_state_incref(rstate);
+}
+
+static void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
+{
+       struct r600_vertex_element *v = (struct r600_vertex_element*)state;
+
+       if (v == NULL)
+               return;
+       if (--v->refcount)
+               return;
+       free(v);
+}
+
+static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_vertex_element *v = (struct r600_vertex_element*)state;
+
+       r600_delete_vertex_element(ctx, rctx->vertex_elements);
+       rctx->vertex_elements = v;
+       if (v) {
+               v->refcount++;
+       }
+}
+
+static void r600_bind_ps_sampler(struct pipe_context *ctx,
+                                       unsigned count, void **states)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+       unsigned i;
+
+       for (i = 0; i < rctx->ps_nsampler; i++) {
+               rctx->ps_sampler[i] = r600_context_state_decref(rctx->ps_sampler[i]);
+       }
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)states[i];
+               rctx->ps_sampler[i] = r600_context_state_incref(rstate);
+       }
+       rctx->ps_nsampler = count;
+}
+
+static void r600_bind_vs_sampler(struct pipe_context *ctx,
+                                       unsigned count, void **states)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+       unsigned i;
+
+       for (i = 0; i < rctx->vs_nsampler; i++) {
+               rctx->vs_sampler[i] = r600_context_state_decref(rctx->vs_sampler[i]);
+       }
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)states[i];
+               rctx->vs_sampler[i] = r600_context_state_incref(rstate);
+       }
+       rctx->vs_nsampler = count;
+}
 
 static void r600_delete_state(struct pipe_context *ctx, void *state)
 {
-       struct radeon_state *rstate = state;
+       struct r600_context_state *rstate = (struct r600_context_state *)state;
 
-       radeon_state_decref(rstate);
+       r600_context_state_decref(rstate);
 }
 
-static void *r600_create_blend_state(struct pipe_context *ctx,
-                                       const struct pipe_blend_state *state)
+static void r600_set_blend_color(struct pipe_context *ctx,
+                                       const struct pipe_blend_color *color)
+{
+}
+
+static void r600_set_clip_state(struct pipe_context *ctx,
+                               const struct pipe_clip_state *state)
+{
+}
+
+static void r600_set_constant_buffer(struct pipe_context *ctx,
+                                       uint shader, uint index,
+                                       struct pipe_resource *buffer)
 {
        struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct r600_context *rctx = r600_context(ctx);
+       unsigned nconstant = 0, i, type, id;
+       struct radeon_state *rstate;
+       struct pipe_transfer *transfer;
+       u32 *ptr;
+
+       switch (shader) {
+       case PIPE_SHADER_VERTEX:
+               id = R600_VS_CONSTANT;
+               type = R600_VS_CONSTANT_TYPE;
+               break;
+       case PIPE_SHADER_FRAGMENT:
+               id = R600_PS_CONSTANT;
+               type = R600_PS_CONSTANT_TYPE;
+               break;
+       default:
+               fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader);
+               return;
+       }
+       if (buffer && buffer->width0 > 0) {
+               nconstant = buffer->width0 / 16;
+               ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
+               if (ptr == NULL)
+                       return;
+               for (i = 0; i < nconstant; i++) {
+                       rstate = radeon_state(rscreen->rw, type, id + i);
+                       if (rstate == NULL)
+                               return;
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
+                       if (radeon_state_pm4(rstate))
+                               return;
+                       if (radeon_draw_set_new(rctx->draw, rstate))
+                               return;
+               }
+               pipe_buffer_unmap(ctx, buffer, transfer);
+       }
+}
+
+static void r600_set_ps_sampler_view(struct pipe_context *ctx,
+                                       unsigned count,
+                                       struct pipe_sampler_view **views)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+       unsigned i;
+
+       for (i = 0; i < rctx->ps_nsampler_view; i++) {
+               rctx->ps_sampler_view[i] = r600_context_state_decref(rctx->ps_sampler_view[i]);
+       }
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)views[i];
+               rctx->ps_sampler_view[i] = r600_context_state_incref(rstate);
+       }
+       rctx->ps_nsampler_view = count;
+}
+
+static void r600_set_vs_sampler_view(struct pipe_context *ctx,
+                                       unsigned count,
+                                       struct pipe_sampler_view **views)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+       unsigned i;
+
+       for (i = 0; i < rctx->vs_nsampler_view; i++) {
+               rctx->vs_sampler_view[i] = r600_context_state_decref(rctx->vs_sampler_view[i]);
+       }
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)views[i];
+               rctx->vs_sampler_view[i] = r600_context_state_incref(rstate);
+       }
+       rctx->vs_nsampler_view = count;
+}
+
+static void r600_set_framebuffer_state(struct pipe_context *ctx,
+                                       const struct pipe_framebuffer_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+
+       rstate = r600_context_state(rctx, pipe_framebuffer_type, state);
+       r600_bind_state(ctx, rstate);
+}
+
+static void r600_set_polygon_stipple(struct pipe_context *ctx,
+                                        const struct pipe_poly_stipple *state)
+{
+}
+
+static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
+{
+}
+
+static void r600_set_scissor_state(struct pipe_context *ctx,
+                                       const struct pipe_scissor_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+
+       rstate = r600_context_state(rctx, pipe_scissor_type, state);
+       r600_bind_state(ctx, rstate);
+}
+
+static void r600_set_stencil_ref(struct pipe_context *ctx,
+                               const struct pipe_stencil_ref *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+
+       rstate = r600_context_state(rctx, pipe_stencil_ref_type, state);
+       r600_bind_state(ctx, rstate);
+}
+
+static void r600_set_vertex_buffers(struct pipe_context *ctx,
+                                       unsigned count,
+                                       const struct pipe_vertex_buffer *buffers)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       unsigned i;
+
+       for (i = 0; i < rctx->nvertex_buffer; i++) {
+               pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL);
+       }
+       memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
+       for (i = 0; i < count; i++) {
+               rctx->vertex_buffer[i].buffer = NULL;
+               pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer);
+       }
+       rctx->nvertex_buffer = count;
+}
+
+static void r600_set_viewport_state(struct pipe_context *ctx,
+                                       const struct pipe_viewport_state *state)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_context_state *rstate;
+
+       rstate = r600_context_state(rctx, pipe_viewport_type, state);
+       r600_bind_state(ctx, rstate);
+}
+
+void r600_init_state_functions(struct r600_context *rctx)
+{
+       rctx->context.create_blend_state = r600_create_blend_state;
+       rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
+       rctx->context.create_fs_state = r600_create_shader_state;
+       rctx->context.create_rasterizer_state = r600_create_rs_state;
+       rctx->context.create_sampler_state = r600_create_sampler_state;
+       rctx->context.create_sampler_view = r600_create_sampler_view;
+       rctx->context.create_vertex_elements_state = r600_create_vertex_elements;
+       rctx->context.create_vs_state = r600_create_shader_state;
+       rctx->context.bind_blend_state = r600_bind_state;
+       rctx->context.bind_depth_stencil_alpha_state = r600_bind_state;
+       rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler;
+       rctx->context.bind_fs_state = r600_bind_ps_shader;
+       rctx->context.bind_rasterizer_state = r600_bind_state;
+       rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements;
+       rctx->context.bind_vertex_sampler_states = r600_bind_vs_sampler;
+       rctx->context.bind_vs_state = r600_bind_vs_shader;
+       rctx->context.delete_blend_state = r600_delete_state;
+       rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
+       rctx->context.delete_fs_state = r600_delete_state;
+       rctx->context.delete_rasterizer_state = r600_delete_state;
+       rctx->context.delete_sampler_state = r600_delete_state;
+       rctx->context.delete_vertex_elements_state = r600_delete_vertex_element;
+       rctx->context.delete_vs_state = r600_delete_state;
+       rctx->context.set_blend_color = r600_set_blend_color;
+       rctx->context.set_clip_state = r600_set_clip_state;
+       rctx->context.set_constant_buffer = r600_set_constant_buffer;
+       rctx->context.set_fragment_sampler_views = r600_set_ps_sampler_view;
+       rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
+       rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
+       rctx->context.set_sample_mask = r600_set_sample_mask;
+       rctx->context.set_scissor_state = r600_set_scissor_state;
+       rctx->context.set_stencil_ref = r600_set_stencil_ref;
+       rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
+       rctx->context.set_vertex_sampler_views = r600_set_vs_sampler_view;
+       rctx->context.set_viewport_state = r600_set_viewport_state;
+       rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
+}
+
+struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate)
+{
+       if (rstate == NULL)
+               return NULL;
+       rstate->refcount++;
+       return rstate;
+}
+
+struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate)
+{
+       unsigned i;
+
+       if (rstate == NULL)
+               return NULL;
+       if (--rstate->refcount)
+               return NULL;
+       switch (rstate->type) {
+       case pipe_sampler_view_type:
+               pipe_resource_reference(&rstate->state.sampler_view.texture, NULL);
+               break;
+       case pipe_framebuffer_type:
+               for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) {
+                       pipe_surface_reference(&rstate->state.framebuffer.cbufs[i], NULL);
+               }
+               pipe_surface_reference(&rstate->state.framebuffer.zsbuf, NULL);
+               break;
+       case pipe_viewport_type:
+       case pipe_depth_type:
+       case pipe_rasterizer_type:
+       case pipe_poly_stipple_type:
+       case pipe_scissor_type:
+       case pipe_clip_type:
+       case pipe_stencil_type:
+       case pipe_alpha_type:
+       case pipe_dsa_type:
+       case pipe_blend_type:
+       case pipe_stencil_ref_type:
+       case pipe_shader_type:
+       case pipe_sampler_type:
+               break;
+       default:
+               R600_ERR("invalid type %d\n", rstate->type);
+               return NULL;
+       }
+       radeon_state_decref(rstate->rstate);
+       FREE(rstate);
+       return NULL;
+}
+
+struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state)
+{
+       struct r600_context_state *rstate = CALLOC_STRUCT(r600_context_state);
+       const union pipe_states *states = state;
+       unsigned i;
+       int r;
+
+       if (rstate == NULL)
+               return NULL;
+       rstate->type = type;
+       rstate->refcount = 1;
+
+       switch (rstate->type) {
+       case pipe_sampler_view_type:
+               rstate->state.sampler_view = (*states).sampler_view;
+               rstate->state.sampler_view.texture = NULL;
+               break;
+       case pipe_framebuffer_type:
+               rstate->state.framebuffer = (*states).framebuffer;
+               for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) {
+                       pipe_surface_reference(&rstate->state.framebuffer.cbufs[i],
+                                               (*states).framebuffer.cbufs[i]);
+               }
+               pipe_surface_reference(&rstate->state.framebuffer.zsbuf,
+                                       (*states).framebuffer.zsbuf);
+               break;
+       case pipe_viewport_type:
+               rstate->state.viewport = (*states).viewport;
+               break;
+       case pipe_depth_type:
+               rstate->state.depth = (*states).depth;
+               break;
+       case pipe_rasterizer_type:
+               rstate->state.rasterizer = (*states).rasterizer;
+               break;
+       case pipe_poly_stipple_type:
+               rstate->state.poly_stipple = (*states).poly_stipple;
+               break;
+       case pipe_scissor_type:
+               rstate->state.scissor = (*states).scissor;
+               break;
+       case pipe_clip_type:
+               rstate->state.clip = (*states).clip;
+               break;
+       case pipe_stencil_type:
+               rstate->state.stencil = (*states).stencil;
+               break;
+       case pipe_alpha_type:
+               rstate->state.alpha = (*states).alpha;
+               break;
+       case pipe_dsa_type:
+               rstate->state.dsa = (*states).dsa;
+               break;
+       case pipe_blend_type:
+               rstate->state.blend = (*states).blend;
+               break;
+       case pipe_stencil_ref_type:
+               rstate->state.stencil_ref = (*states).stencil_ref;
+               break;
+       case pipe_shader_type:
+               rstate->state.shader = (*states).shader;
+               r =  r600_pipe_shader_create(&rctx->context, rstate, rstate->state.shader.tokens);
+               if (r) {
+                       r600_context_state_decref(rstate);
+                       return NULL;
+               }
+               break;
+       case pipe_sampler_type:
+               rstate->state.sampler = (*states).sampler;
+               break;
+       default:
+               R600_ERR("invalid type %d\n", rstate->type);
+               FREE(rstate);
+               return NULL;
+       }
+       return rstate;
+}
+
+static struct radeon_state *r600_blend(struct r600_context *rctx)
+{
+       struct r600_screen *rscreen = rctx->screen;
        struct radeon_state *rstate;
 
        rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND);
@@ -69,36 +608,19 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
        return rstate;
 }
 
-static void r600_bind_blend_state(struct pipe_context *ctx, void *state)
+static struct radeon_state *r600_cb0(struct r600_context *rctx)
 {
-       struct r600_context *rctx = r600_context(ctx);
-       radeon_draw_set(rctx->draw, state);
-}
-
-static void r600_set_blend_color(struct pipe_context *ctx,
-                                       const struct pipe_blend_color *color)
-{
-}
-
-static void r600_set_clip_state(struct pipe_context *ctx,
-                               const struct pipe_clip_state *state)
-{
-}
-
-static void r600_set_framebuffer_state(struct pipe_context *ctx,
-                                       const struct pipe_framebuffer_state *state)
-{
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_context *rctx = r600_context(ctx);
+       struct r600_screen *rscreen = rctx->screen;
        struct r600_resource_texture *rtex;
        struct r600_resource *rbuffer;
        struct radeon_state *rstate;
+       const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer;
        unsigned level = state->cbufs[0]->level;
        unsigned pitch, slice;
 
        rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, R600_CB0);
        if (rstate == NULL)
-               return;
+               return NULL;
        rtex = (struct r600_resource_texture*)state->cbufs[0]->texture;
        rbuffer = &rtex->resource;
        rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
@@ -120,70 +642,53 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        rstate->states[R600_CB0__CB_COLOR0_MASK] = 0x00000000;
        if (radeon_state_pm4(rstate)) {
                radeon_state_decref(rstate);
-               return;
+               return NULL;
        }
-       radeon_draw_set_new(rctx->draw, rstate);
-       rctx->db = radeon_state_decref(rctx->db);
-       if(state->zsbuf) {
-               rtex = (struct r600_resource_texture*)state->zsbuf->texture;
-               rbuffer = &rtex->resource;
-               rctx->db = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB);
-               if(rctx->db == NULL)
-                    return;
-               rctx->db->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
-               rctx->db->nbo = 1;
-               rctx->db->placement[0] = RADEON_GEM_DOMAIN_VRAM;
-               level = state->zsbuf->level;
-               pitch = rtex->pitch[level] / 8 - 1;
-               slice = rtex->pitch[level] * state->zsbuf->height / 64 - 1;
-
-               rctx->db->states[R600_DB__DB_DEPTH_BASE] = 0x00000000;
-               rctx->db->states[R600_DB__DB_DEPTH_INFO] = 0x00010006;
-               rctx->db->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000;
-               rctx->db->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1;
-               rctx->db->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) |
-                                               S_028000_SLICE_TILE_MAX(slice);
-       } else 
-               rctx->db = NULL;
-       rctx->fb_state = *state;
-}
-
-static void *r600_create_fs_state(struct pipe_context *ctx,
-                                       const struct pipe_shader_state *shader)
-{
-       return r600_pipe_shader_create(ctx, shader->tokens);
-}
-
-static void r600_bind_fs_state(struct pipe_context *ctx, void *state)
-{
-       struct r600_context *rctx = r600_context(ctx);
-
-       rctx->ps_shader = state;
+       return rstate;
 }
 
-static void *r600_create_vs_state(struct pipe_context *ctx,
-                                       const struct pipe_shader_state *shader)
+static struct radeon_state *r600_db(struct r600_context *rctx)
 {
-       return r600_pipe_shader_create(ctx, shader->tokens);
-}
+       struct r600_screen *rscreen = rctx->screen;
+       struct r600_resource_texture *rtex;
+       struct r600_resource *rbuffer;
+       struct radeon_state *rstate;
+       const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer;
+       unsigned level = state->cbufs[0]->level;
+       unsigned pitch, slice;
 
-static void r600_bind_vs_state(struct pipe_context *ctx, void *state)
-{
-       struct r600_context *rctx = r600_context(ctx);
+       if (state->zsbuf == NULL)
+               return NULL;
 
-       rctx->vs_shader = state;
-}
+       rstate = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB);
+       if (rstate == NULL)
+               return NULL;
 
-static void r600_set_polygon_stipple(struct pipe_context *ctx,
-                                        const struct pipe_poly_stipple *state)
-{
+       rtex = (struct r600_resource_texture*)state->zsbuf->texture;
+       rbuffer = &rtex->resource;
+       rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+       rstate->nbo = 1;
+       rstate->placement[0] = RADEON_GEM_DOMAIN_VRAM;
+       level = state->zsbuf->level;
+       pitch = rtex->pitch[level] / 8 - 1;
+       slice = rtex->pitch[level] * state->zsbuf->height / 64 - 1;
+       rstate->states[R600_DB__DB_DEPTH_BASE] = 0x00000000;
+       rstate->states[R600_DB__DB_DEPTH_INFO] = 0x00010006;
+       rstate->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000;
+       rstate->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1;
+       rstate->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) |
+                                               S_028000_SLICE_TILE_MAX(slice);
+       if (radeon_state_pm4(rstate)) {
+               radeon_state_decref(rstate);
+               return NULL;
+       }
+       return rstate;
 }
 
-static void *r600_create_rs_state(struct pipe_context *ctx,
-                                       const struct pipe_rasterizer_state *state)
+static struct radeon_state *r600_rasterizer(struct r600_context *rctx)
 {
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_context *rctx = r600_context(ctx);
+       const struct pipe_rasterizer_state *state = &rctx->rasterizer->state.rasterizer;
+       struct r600_screen *rscreen = rctx->screen;
        struct radeon_state *rstate;
 
        rctx->flat_shade = state->flatshade;
@@ -220,10 +725,102 @@ R600_ERR("flat shade with texture broke tex coord interp\n");
        return rstate;
 }
 
-static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
+static struct radeon_state *r600_scissor(struct r600_context *rctx)
 {
-       struct r600_context *rctx = r600_context(ctx);
-       radeon_draw_set(rctx->draw, state);
+       const struct pipe_scissor_state *state = &rctx->scissor->state.scissor;
+       struct r600_screen *rscreen = rctx->screen;
+       struct radeon_state *rstate;
+       u32 tl, br;
+
+       tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1);
+       br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy);
+       rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR);
+       if (rstate == NULL)
+               return NULL;
+       rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br;
+       rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000;
+       rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_BR] = br;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_RULE] = 0x0000FFFF;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_BR] = br;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_BR] = br;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_BR] = br;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_BR] = br;
+       rstate->states[R600_SCISSOR__PA_SC_EDGERULE] = 0xAAAAAAAA;
+       rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR] = br;
+       rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL] = tl;
+       rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br;
+       if (radeon_state_pm4(rstate)) {
+               radeon_state_decref(rstate);
+               return NULL;
+       }
+       return rstate;
+}
+
+static struct radeon_state *r600_viewport(struct r600_context *rctx)
+{
+       const struct pipe_viewport_state *state = &rctx->viewport->state.viewport;
+       struct r600_screen *rscreen = rctx->screen;
+       struct radeon_state *rstate;
+
+       rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT);
+       if (rstate == NULL)
+               return NULL;
+       rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000;
+       rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;
+       rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = fui(state->scale[0]);
+       rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = fui(state->scale[1]);
+       rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = fui(state->scale[2]);
+       rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = fui(state->translate[0]);
+       rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = fui(state->translate[1]);
+       rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = fui(state->translate[2]);
+       rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F;
+       if (radeon_state_pm4(rstate)) {
+               radeon_state_decref(rstate);
+               return NULL;
+       }
+       return rstate;
+}
+
+static struct radeon_state *r600_dsa(struct r600_context *rctx)
+{
+       const struct pipe_depth_stencil_alpha_state *state = &rctx->dsa->state.dsa;
+       struct r600_screen *rscreen = rctx->screen;
+       struct radeon_state *rstate;
+       unsigned db_depth_control;
+
+       rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
+       if (rstate == NULL)
+               return NULL;
+       db_depth_control = 0x00700700 | S_028800_Z_ENABLE(state->depth.enabled) | S_028800_Z_WRITE_ENABLE(state->depth.writemask) | S_028800_ZFUNC(state->depth.func);
+       
+       rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000;
+       rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
+       rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000;
+       rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00;
+       rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00;
+       rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000;
+       rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000;
+       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_RENDER_CONTROL] = 0x00000060;
+       rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
+       rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000;
+       rstate->states[R600_DSA__DB_PRELOAD_CONTROL] = 0x00000000;
+       rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
+       if (radeon_state_pm4(rstate)) {
+               radeon_state_decref(rstate);
+               return NULL;
+       }
+       return rstate;
 }
 
 static inline unsigned r600_tex_wrap(unsigned wrap)
@@ -296,13 +893,14 @@ static inline unsigned r600_tex_compare(unsigned compare)
        }
 }
 
-static void *r600_create_sampler_state(struct pipe_context *ctx,
-                                       const struct pipe_sampler_state *state)
+static struct radeon_state *r600_sampler(struct r600_context *rctx,
+                               const struct pipe_sampler_state *state,
+                               unsigned id)
 {
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct r600_screen *rscreen = rctx->screen;
        struct radeon_state *rstate;
 
-       rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, R600_PS_SAMPLER);
+       rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, id);
        if (rstate == NULL)
                return NULL;
        rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0] =
@@ -314,33 +912,16 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
                        S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) |
                        S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func));
        /* FIXME LOD it depends on texture base level ... */
-       rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0] =
-                       S_03C004_MIN_LOD(0) |
-                       S_03C004_MAX_LOD(0) |
-                       S_03C004_LOD_BIAS(0);
-       rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1);
-       if (radeon_state_pm4(rstate)) {
-               radeon_state_decref(rstate);
-               return NULL;
-       }
-       return rstate;
-}
-
-static void r600_bind_sampler_states(struct pipe_context *ctx,
-                                       unsigned count, void **states)
-{
-       struct r600_context *rctx = r600_context(ctx);
-       unsigned i;
-
-       /* FIXME split VS/PS/GS sampler */
-       for (i = 0; i < count; i++) {
-               rctx->ps_sampler[i] = radeon_state_decref(rctx->ps_sampler[i]);
-       }
-       rctx->nps_sampler = count;
-       for (i = 0; i < count; i++) {
-               rctx->ps_sampler[i] = radeon_state_incref(states[i]);
-               rctx->ps_sampler[i]->id = R600_PS_SAMPLER + i;
+       rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0] =
+                       S_03C004_MIN_LOD(0) |
+                       S_03C004_MAX_LOD(0) |
+                       S_03C004_LOD_BIAS(0);
+       rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1);
+       if (radeon_state_pm4(rstate)) {
+               radeon_state_decref(rstate);
+               return NULL;
        }
+       return rstate;
 }
 
 static inline unsigned r600_tex_swizzle(unsigned swizzle)
@@ -390,57 +971,47 @@ static inline unsigned r600_tex_dim(unsigned dim)
        }
 }
 
-static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx,
-                                                         struct pipe_resource *texture,
-                                                         const struct pipe_sampler_view *view)
+static struct radeon_state *r600_resource(struct r600_context *rctx,
+                                       const struct pipe_sampler_view *view,
+                                       unsigned id)
 {
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_texture_resource *rtexture;
+       struct r600_screen *rscreen = rctx->screen;
        const struct util_format_description *desc;
        struct r600_resource_texture *tmp;
        struct r600_resource *rbuffer;
+       struct radeon_state *rstate;
        unsigned format;
 
-       if (r600_conv_pipe_format(texture->format, &format))
+       if (r600_conv_pipe_format(view->texture->format, &format))
                return NULL;
-       rtexture = CALLOC_STRUCT(r600_texture_resource);
-       if (rtexture == NULL)
-               return NULL;
-       desc = util_format_description(texture->format);
+       desc = util_format_description(view->texture->format);
        assert(desc == NULL);
-       rtexture->state = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, R600_PS_RESOURCE);
-       if (rtexture->state == NULL) {
-               FREE(rtexture);
+       rstate = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, id);
+       if (rstate == NULL) {
                return NULL;
        }
-       rtexture->view = *view;
-       rtexture->view.reference.count = 1;
-       rtexture->view.texture = NULL;
-       pipe_resource_reference(&rtexture->view.texture, texture);
-       rtexture->view.context = ctx;
-
-       tmp = (struct r600_resource_texture*)texture;
+       tmp = (struct r600_resource_texture*)view->texture;
        rbuffer = &tmp->resource;
-       rtexture->state->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
-       rtexture->state->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
-       rtexture->state->nbo = 2;
-       rtexture->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
-       rtexture->state->placement[1] = RADEON_GEM_DOMAIN_GTT;
-       rtexture->state->placement[2] = RADEON_GEM_DOMAIN_GTT;
-       rtexture->state->placement[3] = RADEON_GEM_DOMAIN_GTT;
+       rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+       rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+       rstate->nbo = 2;
+       rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+       rstate->placement[1] = RADEON_GEM_DOMAIN_GTT;
+       rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
+       rstate->placement[3] = RADEON_GEM_DOMAIN_GTT;
 
        /* FIXME properly handle first level != 0 */
-       rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD0] =
-                       S_038000_DIM(r600_tex_dim(texture->target)) |
+       rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD0] =
+                       S_038000_DIM(r600_tex_dim(view->texture->target)) |
                        S_038000_PITCH((tmp->pitch[0] / 8) - 1) |
-                       S_038000_TEX_WIDTH(texture->width0 - 1);
-       rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD1] =
-                       S_038004_TEX_HEIGHT(texture->height0 - 1) |
-                       S_038004_TEX_DEPTH(texture->depth0 - 1) |
+                       S_038000_TEX_WIDTH(view->texture->width0 - 1);
+       rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD1] =
+                       S_038004_TEX_HEIGHT(view->texture->height0 - 1) |
+                       S_038004_TEX_DEPTH(view->texture->depth0 - 1) |
                        S_038004_DATA_FORMAT(format);
-       rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0;
-       rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8;
-       rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD4] =
+       rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0;
+       rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8;
+       rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD4] =
                        S_038010_FORMAT_COMP_X(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
                        S_038010_FORMAT_COMP_Y(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
                        S_038010_FORMAT_COMP_Z(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
@@ -453,225 +1024,12 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
                        S_038010_DST_SEL_Z(r600_tex_swizzle(view->swizzle_b)) |
                        S_038010_DST_SEL_W(r600_tex_swizzle(view->swizzle_a)) |
                        S_038010_BASE_LEVEL(view->first_level);
-       rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD5] =
+       rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD5] =
                        S_038014_LAST_LEVEL(view->last_level) |
                        S_038014_BASE_ARRAY(0) |
                        S_038014_LAST_ARRAY(0);
-       rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD6] =
+       rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD6] =
                        S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE);
-       return &rtexture->view;
-}
-
-static void r600_sampler_view_destroy(struct pipe_context *ctx,
-                                     struct pipe_sampler_view *view)
-{
-       struct r600_texture_resource *texture;
-
-       if (view == NULL)
-               return;
-       texture  = LIST_ENTRY(struct r600_texture_resource, view, view);
-       radeon_state_decref(texture->state);
-       FREE(texture);
-}
-
-static void r600_set_fragment_sampler_views(struct pipe_context *ctx,
-                                           unsigned count,
-                                           struct pipe_sampler_view **views)
-{
-       struct r600_texture_resource *rtexture;
-       struct r600_context *rctx = r600_context(ctx);
-       struct pipe_sampler_view *tmp;
-       unsigned i, real_num_views = 0;
-
-       if (views == NULL)
-               return;
-
-       for (i = 0; i < count; i++) {
-               if (views[i])
-                       real_num_views++;
-       }
-
-       for (i = 0; i < rctx->nps_view; i++) {
-               tmp = &rctx->ps_view[i]->view;
-               pipe_sampler_view_reference(&tmp, NULL);
-               rctx->ps_view[i] = NULL;
-       }
-       rctx->nps_view = real_num_views;
-       for (i = 0; i < count; i++) {
-
-               if (!views[i])
-                       continue;
-               rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view);
-               rctx->ps_view[i] = rtexture;
-               tmp = NULL;
-               pipe_sampler_view_reference(&tmp, views[i]);
-               rtexture->state->id = R600_PS_RESOURCE + i;
-       }
-}
-
-static void r600_set_vertex_sampler_views(struct pipe_context *ctx,
-                                         unsigned count,
-                                         struct pipe_sampler_view **views)
-{
-       struct r600_texture_resource *rtexture;
-       struct r600_context *rctx = r600_context(ctx);
-       struct pipe_sampler_view *tmp;
-       unsigned i, real_num_views = 0;
-
-       if (views == NULL)
-               return;
-
-       for (i = 0; i < count; i++) {
-               if (views[i])
-                       real_num_views++;
-       }
-       for (i = 0; i < rctx->nvs_view; i++) {
-               tmp = &rctx->vs_view[i]->view;
-               pipe_sampler_view_reference(&tmp, NULL);
-               rctx->vs_view[i] = NULL;
-       }
-       rctx->nvs_view = real_num_views;
-       for (i = 0; i < count; i++) {
-               if (!views[i])
-                       continue;
-               rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view);
-               rctx->vs_view[i] = rtexture;
-               tmp = NULL;
-               pipe_sampler_view_reference(&tmp, views[i]);
-               rtexture->state->id = R600_VS_RESOURCE + i;
-       }
-}
-
-static void r600_set_scissor_state(struct pipe_context *ctx,
-                                       const struct pipe_scissor_state *state)
-{
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_context *rctx = r600_context(ctx);
-       struct radeon_state *rstate;
-       u32 tl, br;
-
-       tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1);
-       br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy);
-       rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR);
-       if (rstate == NULL)
-               return;
-       rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br;
-       rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000;
-       rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_BR] = br;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_RULE] = 0x0000FFFF;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_BR] = br;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_BR] = br;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_BR] = br;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_BR] = br;
-       rstate->states[R600_SCISSOR__PA_SC_EDGERULE] = 0xAAAAAAAA;
-       rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR] = br;
-       rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL] = tl;
-       rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br;
-       if (radeon_state_pm4(rstate)) {
-               radeon_state_decref(rstate);
-               return;
-       }
-       radeon_draw_set_new(rctx->draw, rstate);
-}
-
-static void r600_set_viewport_state(struct pipe_context *ctx,
-                                       const struct pipe_viewport_state *state)
-{
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_context *rctx = r600_context(ctx);
-       struct radeon_state *rstate;
-
-       rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT);
-       if (rstate == NULL)
-               return;
-       rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000;
-       rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;
-       rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = fui(state->scale[0]);
-       rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = fui(state->scale[1]);
-       rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = fui(state->scale[2]);
-       rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = fui(state->translate[0]);
-       rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = fui(state->translate[1]);
-       rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = fui(state->translate[2]);
-       rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F;
-       if (radeon_state_pm4(rstate)) {
-               radeon_state_decref(rstate);
-               return;
-       }
-       radeon_draw_set_new(rctx->draw, rstate);
-       rctx->viewport = *state;
-}
-
-static void r600_set_vertex_buffers(struct pipe_context *ctx,
-                                       unsigned count,
-                                       const struct pipe_vertex_buffer *buffers)
-{
-       struct r600_context *rctx = r600_context(ctx);
-
-       memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
-       rctx->nvertex_buffer = count;
-}
-
-
-static void *r600_create_vertex_elements_state(struct pipe_context *ctx,
-                                              unsigned count,
-                                              const struct pipe_vertex_element *elements)
-{
-       struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state);
-
-       assert(count < 32);
-       v->count = count;
-       memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
-       return v;
-}
-
-static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state)
-{
-       struct r600_context *rctx = r600_context(ctx);
-       struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state;
-
-       rctx->vertex_elements = v;
-}
-
-static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state)
-{
-       FREE(state);
-}
-
-static void *r600_create_dsa_state(struct pipe_context *ctx,
-                                       const struct pipe_depth_stencil_alpha_state *state)
-{
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct radeon_state *rstate;
-       unsigned db_depth_control;
-
-       rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
-       if (rstate == NULL)
-               return NULL;
-       db_depth_control = 0x00700700 | S_028800_Z_ENABLE(state->depth.enabled) | S_028800_Z_WRITE_ENABLE(state->depth.writemask) | S_028800_ZFUNC(state->depth.func);
-       
-       rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000;
-       rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
-       rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000;
-       rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00;
-       rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00;
-       rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000;
-       rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000;
-       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_RENDER_CONTROL] = 0x00000060;
-       rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
-       rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000;
-       rstate->states[R600_DSA__DB_PRELOAD_CONTROL] = 0x00000000;
-       rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
        if (radeon_state_pm4(rstate)) {
                radeon_state_decref(rstate);
                return NULL;
@@ -679,105 +1037,100 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
        return rstate;
 }
 
-static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
-{
-       struct r600_context *rctx = r600_context(ctx);
-       radeon_draw_set(rctx->draw, state);
-}
-
-static void r600_set_constant_buffer(struct pipe_context *ctx,
-                                    uint shader, uint index,
-                                    struct pipe_resource *buffer)
+int r600_context_hw_states(struct r600_context *rctx)
 {
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_context *rctx = r600_context(ctx);
-       unsigned nconstant = 0, i, type, id;
-       struct radeon_state *rstate;
-       struct pipe_transfer *transfer;
-       u32 *ptr;
-
-       switch (shader) {
-       case PIPE_SHADER_VERTEX:
-               id = R600_VS_CONSTANT;
-               type = R600_VS_CONSTANT_TYPE;
-               break;
-       case PIPE_SHADER_FRAGMENT:
-               id = R600_PS_CONSTANT;
-               type = R600_PS_CONSTANT_TYPE;
-               break;
-       default:
-               fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader);
-               return;
+       unsigned i;
+       int r;
+
+       /* free previous TODO determine what need to be updated, what
+        * doesn't
+        */
+       //radeon_state_decref(rctx->hw_states.config);
+       //radeon_state_decref(rctx->hw_states.cb_cntl);
+       radeon_state_decref(rctx->hw_states.db);
+       radeon_state_decref(rctx->hw_states.rasterizer);
+       radeon_state_decref(rctx->hw_states.scissor);
+       radeon_state_decref(rctx->hw_states.dsa);
+       radeon_state_decref(rctx->hw_states.blend);
+       radeon_state_decref(rctx->hw_states.viewport);
+       radeon_state_decref(rctx->hw_states.cb0);
+       for (i = 0; i < rctx->hw_states.ps_nresource; i++) {
+               radeon_state_decref(rctx->hw_states.ps_resource[i]);
+               rctx->hw_states.ps_resource[i] = NULL;
        }
-       if (buffer && buffer->width0 > 0) {
-               nconstant = buffer->width0 / 16;
-               ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
-               if (ptr == NULL)
-                       return;
-               for (i = 0; i < nconstant; i++) {
-                       rstate = radeon_state(rscreen->rw, type, id + i);
-                       if (rstate == NULL)
-                               return;
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
-                       if (radeon_state_pm4(rstate))
-                               return;
-                       if (radeon_draw_set_new(rctx->draw, rstate))
-                               return;
+       rctx->hw_states.ps_nresource = 0;
+       for (i = 0; i < rctx->hw_states.ps_nsampler; i++) {
+               radeon_state_decref(rctx->hw_states.ps_sampler[i]);
+               rctx->hw_states.ps_sampler[i] = NULL;
+       }
+       rctx->hw_states.ps_nsampler = 0;
+
+       /* build new states */
+       rctx->hw_states.rasterizer = r600_rasterizer(rctx);
+       rctx->hw_states.scissor = r600_scissor(rctx);
+       rctx->hw_states.dsa = r600_dsa(rctx);
+       rctx->hw_states.blend = r600_blend(rctx);
+       rctx->hw_states.viewport = r600_viewport(rctx);
+       rctx->hw_states.cb0 = r600_cb0(rctx);
+       rctx->hw_states.db = r600_db(rctx);
+       for (i = 0; i < rctx->ps_nsampler; i++) {
+               if (rctx->ps_sampler[i]) {
+                       rctx->hw_states.ps_sampler[i] = r600_sampler(rctx,
+                                                       &rctx->ps_sampler[i]->state.sampler,
+                                                       R600_PS_SAMPLER + i);
                }
-               pipe_buffer_unmap(ctx, buffer, transfer);
        }
-}
-
-static void r600_set_stencil_ref(struct pipe_context *ctx,
-                               const struct pipe_stencil_ref *sr)
-{
-       struct r600_context *rctx = r600_context(ctx);
-       rctx->stencil_ref = *sr;
-}
-
-static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
-{
-}
-
-void r600_init_state_functions(struct r600_context *rctx)
-{
-       rctx->context.set_sample_mask = r600_set_sample_mask;
-       rctx->context.create_blend_state = r600_create_blend_state;
-       rctx->context.bind_blend_state = r600_bind_blend_state;
-       rctx->context.delete_blend_state = r600_delete_state;
-       rctx->context.set_blend_color = r600_set_blend_color;
-       rctx->context.set_clip_state = r600_set_clip_state;
-       rctx->context.set_constant_buffer = r600_set_constant_buffer;
-       rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
-       rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
-       rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
-       rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
-       rctx->context.create_fs_state = r600_create_fs_state;
-       rctx->context.bind_fs_state = r600_bind_fs_state;
-       rctx->context.delete_fs_state = r600_delete_state;
-       rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
-       rctx->context.create_rasterizer_state = r600_create_rs_state;
-       rctx->context.bind_rasterizer_state = r600_bind_rs_state;
-       rctx->context.delete_rasterizer_state = r600_delete_state;
-       rctx->context.create_sampler_state = r600_create_sampler_state;
-       rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states;
-       rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states;
-       rctx->context.delete_sampler_state = r600_delete_state;
-       rctx->context.create_sampler_view = r600_create_sampler_view;
-       rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
-       rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views;
-       rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views;
-       rctx->context.set_scissor_state = r600_set_scissor_state;
-       rctx->context.set_viewport_state = r600_set_viewport_state;
-       rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
-       rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state;
-       rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state;
-       rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state;
-       rctx->context.create_vs_state = r600_create_vs_state;
-       rctx->context.bind_vs_state = r600_bind_vs_state;
-       rctx->context.delete_vs_state = r600_delete_state;
-       rctx->context.set_stencil_ref = r600_set_stencil_ref;
+       rctx->hw_states.ps_nsampler = rctx->ps_nsampler;
+       for (i = 0; i < rctx->ps_nsampler_view; i++) {
+               if (rctx->ps_sampler_view[i]) {
+                       rctx->hw_states.ps_resource[i] = r600_resource(rctx,
+                                                       &rctx->ps_sampler_view[i]->state.sampler_view,
+                                                       R600_PS_RESOURCE + i);
+               }
+       }
+       rctx->hw_states.ps_nresource = rctx->ps_nsampler_view;
+
+       /* bind states */
+       r = radeon_draw_set(rctx->draw, rctx->hw_states.db);
+       if (r)
+               return r;
+       r = radeon_draw_set(rctx->draw, rctx->hw_states.rasterizer);
+       if (r)
+               return r;
+       r = radeon_draw_set(rctx->draw, rctx->hw_states.scissor);
+       if (r)
+               return r;
+       r = radeon_draw_set(rctx->draw, rctx->hw_states.dsa);
+       if (r)
+               return r;
+       r = radeon_draw_set(rctx->draw, rctx->hw_states.blend);
+       if (r)
+               return r;
+       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;
+       r = radeon_draw_set(rctx->draw, rctx->hw_states.config);
+       if (r)
+               return r;
+       r = radeon_draw_set(rctx->draw, rctx->hw_states.cb_cntl);
+       if (r)
+               return r;
+       for (i = 0; i < rctx->hw_states.ps_nresource; i++) {
+               if (rctx->hw_states.ps_resource[i]) {
+                       r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_resource[i]);
+                       if (r)
+                               return r;
+               }
+       }
+       for (i = 0; i < rctx->hw_states.ps_nsampler; i++) {
+               if (rctx->hw_states.ps_sampler[i]) {
+                       r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_sampler[i]);
+                       if (r)
+                               return r;
+               }
+       }
+       return 0;
 }
index 3d87a994c150a4bc0453faf281605d0e552e4fa3..9520792f54d1c353980327cdbccece230170af83 100644 (file)
@@ -30,7 +30,7 @@
 #include "util/u_debug.h"
 #include "radeon_priv.h"
 #include "r600_screen.h"
-#include "r600_texture.h"
+#include "r600_resource.h"
 #include "r600_public.h"
 #include "r600_drm_public.h"
 #include "state_tracker/drm_driver.h"
@@ -45,7 +45,7 @@ boolean r600_buffer_get_handle(struct radeon *rw,
                               struct winsys_handle *whandle)
 {
        struct drm_gem_flink flink;
-       struct r600_buffer* rbuffer = (struct r600_buffer*)buf;
+       struct r600_resource* rbuffer = (struct r600_buffer*)buf;
 
        if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
                if (!rbuffer->flink) {