radeonsi: implement uniform buffer objects
[mesa.git] / src / gallium / drivers / radeonsi / si_state.c
index 3be17a595e0785bcf5390d9fd9e54ecd2e0dbbdb..f6400d8c51a87e5e6a6f5694fc580bc70888dba5 100644 (file)
@@ -377,7 +377,7 @@ static void si_set_clip_state(struct pipe_context *ctx,
        cb.user_buffer = state->ucp;
        cb.buffer_offset = 0;
        cb.buffer_size = 4*4*8;
-       ctx->set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
+       ctx->set_constant_buffer(ctx, PIPE_SHADER_VERTEX, NUM_PIPE_CONST_BUFFERS, &cb);
        pipe_resource_reference(&cb.buffer, NULL);
 
        si_pm4_set_state(rctx, clip, pm4);
@@ -525,6 +525,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
        rs->two_side = state->light_twoside;
        rs->multisample_enable = state->multisample;
        rs->clip_plane_enable = state->clip_plane_enable;
+       rs->line_stipple_enable = state->line_stipple_enable;
 
        polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
                                state->fill_back != PIPE_POLYGON_MODE_FILL);
@@ -744,6 +745,9 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
        if (state->alpha.enabled) {
                dsa->alpha_func = state->alpha.func;
                dsa->alpha_ref = state->alpha.ref_value;
+
+               si_pm4_set_reg(pm4, R_00B030_SPI_SHADER_USER_DATA_PS_0 +
+                              SI_SGPR_ALPHA_REF * 4, fui(dsa->alpha_ref));
        } else {
                dsa->alpha_func = PIPE_FUNC_ALWAYS;
        }
@@ -1762,7 +1766,7 @@ static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
                macro_aspect = cik_macro_tile_aspect(macro_aspect);
                bankw = cik_bank_wh(bankw);
                bankh = cik_bank_wh(bankh);
-               nbanks = cik_num_banks(rscreen->tiling_info.num_banks);
+               nbanks = cik_num_banks(rscreen->b.tiling_info.num_banks);
                pipe_config = cik_db_pipe_config(rscreen->b.info.r600_num_tile_pipes,
                                                 rscreen->b.info.r600_num_backends);
 
@@ -2116,10 +2120,6 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx,
                            rctx->framebuffer.cbufs[0] &&
                            util_format_is_pure_integer(rctx->framebuffer.cbufs[0]->texture->format))
                                key->ps.alpha_func = PIPE_FUNC_ALWAYS;
-
-                       if (key->ps.alpha_func != PIPE_FUNC_ALWAYS &&
-                           key->ps.alpha_func != PIPE_FUNC_NEVER)
-                               key->ps.alpha_ref = rctx->queued.named.dsa->alpha_ref;
                } else {
                        key->ps.alpha_func = PIPE_FUNC_ALWAYS;
                }
@@ -2469,6 +2469,7 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
 
        va = r600_resource_va(ctx->screen, texture);
        va += surflevel[0].offset;
+       va += tmp->mipmap_shift * surflevel[texture->last_level].slice_size;
        view->state[0] = va >> 8;
        view->state[1] = (S_008F14_BASE_ADDRESS_HI(va >> 40) |
                          S_008F14_DATA_FORMAT(format) |
@@ -2480,10 +2481,10 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
                          S_008F1C_DST_SEL_Z(si_map_swizzle(swizzle[2])) |
                          S_008F1C_DST_SEL_W(si_map_swizzle(swizzle[3])) |
                          S_008F1C_BASE_LEVEL(texture->nr_samples > 1 ?
-                                                     0 : state->u.tex.first_level) |
+                                                     0 : state->u.tex.first_level - tmp->mipmap_shift) |
                          S_008F1C_LAST_LEVEL(texture->nr_samples > 1 ?
                                                      util_logbase2(texture->nr_samples) :
-                                                     state->u.tex.last_level) |
+                                                     state->u.tex.last_level - tmp->mipmap_shift) |
                          S_008F1C_TILING_INDEX(si_tile_mode_index(tmp, 0, false)) |
                          S_008F1C_POW2_PAD(texture->last_level > 0) |
                          S_008F1C_TYPE(si_tex_dim(texture->target, texture->nr_samples)));
@@ -2608,14 +2609,21 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
 
 /* XXX consider moving this function to si_descriptors.c for gcc to inline
  *     the si_set_sampler_view calls. LTO might help too. */
-static void si_set_sampler_views(struct r600_context *rctx,
-                                unsigned shader, unsigned count,
+static void si_set_sampler_views(struct pipe_context *ctx,
+                                unsigned shader, unsigned start,
+                                 unsigned count,
                                 struct pipe_sampler_view **views)
 {
+       struct r600_context *rctx = (struct r600_context *)ctx;
        struct r600_textures_info *samplers = &rctx->samplers[shader];
        struct si_pipe_sampler_view **rviews = (struct si_pipe_sampler_view **)views;
        int i;
 
+       if (shader != PIPE_SHADER_VERTEX && shader != PIPE_SHADER_FRAGMENT)
+               return;
+
+       assert(start == 0);
+
        for (i = 0; i < count; i++) {
                if (views[i]) {
                        struct r600_texture *rtex =
@@ -2661,23 +2669,7 @@ static void si_set_sampler_views(struct r600_context *rctx,
        rctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE;
 }
 
-static void si_set_vs_sampler_views(struct pipe_context *ctx, unsigned count,
-                                   struct pipe_sampler_view **views)
-{
-       struct r600_context *rctx = (struct r600_context *)ctx;
-
-       si_set_sampler_views(rctx, PIPE_SHADER_VERTEX, count, views);
-}
-
-static void si_set_ps_sampler_views(struct pipe_context *ctx, unsigned count,
-                                   struct pipe_sampler_view **views)
-{
-       struct r600_context *rctx = (struct r600_context *)ctx;
-
-       si_set_sampler_views(rctx, PIPE_SHADER_FRAGMENT, count, views);
-}
-
-static struct si_pm4_state *si_bind_sampler_states(struct r600_context *rctx, unsigned count,
+static struct si_pm4_state *si_set_sampler_states(struct r600_context *rctx, unsigned count,
                                                   void **states,
                                                   struct r600_textures_info *samplers,
                                                   unsigned user_data_reg)
@@ -2756,7 +2748,7 @@ static void si_bind_vs_sampler_states(struct pipe_context *ctx, unsigned count,
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct si_pm4_state *pm4;
 
-       pm4 = si_bind_sampler_states(rctx, count, states, &rctx->samplers[PIPE_SHADER_VERTEX],
+       pm4 = si_set_sampler_states(rctx, count, states, &rctx->samplers[PIPE_SHADER_VERTEX],
                              R_00B130_SPI_SHADER_USER_DATA_VS_0);
        si_pm4_set_state(rctx, vs_sampler, pm4);
 }
@@ -2766,11 +2758,32 @@ static void si_bind_ps_sampler_states(struct pipe_context *ctx, unsigned count,
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct si_pm4_state *pm4;
 
-       pm4 = si_bind_sampler_states(rctx, count, states, &rctx->samplers[PIPE_SHADER_FRAGMENT],
+       pm4 = si_set_sampler_states(rctx, count, states, &rctx->samplers[PIPE_SHADER_FRAGMENT],
                              R_00B030_SPI_SHADER_USER_DATA_PS_0);
        si_pm4_set_state(rctx, ps_sampler, pm4);
 }
 
+
+static void si_bind_sampler_states(struct pipe_context *ctx, unsigned shader,
+                                   unsigned start, unsigned count,
+                                   void **states)
+{
+   assert(start == 0);
+
+   switch (shader) {
+   case PIPE_SHADER_VERTEX:
+      si_bind_vs_sampler_states(ctx, count, states);
+      break;
+   case PIPE_SHADER_FRAGMENT:
+      si_bind_ps_sampler_states(ctx, count, states);
+      break;
+   default:
+      ;
+   }
+}
+
+
+
 static void si_set_sample_mask(struct pipe_context *ctx, unsigned sample_mask)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
@@ -2918,6 +2931,54 @@ static void *si_create_blend_custom(struct r600_context *rctx, unsigned mode)
        return si_create_blend_state_mode(&rctx->b.b, &blend, mode);
 }
 
+static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
+                                               struct pipe_resource *texture,
+                                               const struct pipe_surface *surf_tmpl)
+{
+       struct r600_texture *rtex = (struct r600_texture*)texture;
+       struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
+       unsigned level = surf_tmpl->u.tex.level;
+
+       if (surface == NULL)
+               return NULL;
+
+       assert(surf_tmpl->u.tex.first_layer <= util_max_layer(texture, surf_tmpl->u.tex.level));
+       assert(surf_tmpl->u.tex.last_layer <= util_max_layer(texture, surf_tmpl->u.tex.level));
+       assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
+
+       pipe_reference_init(&surface->base.reference, 1);
+       pipe_resource_reference(&surface->base.texture, texture);
+       surface->base.context = pipe;
+       surface->base.format = surf_tmpl->format;
+       surface->base.width = rtex->surface.level[level].npix_x;
+       surface->base.height = rtex->surface.level[level].npix_y;
+       surface->base.texture = texture;
+       surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+       surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+       surface->base.u.tex.level = level;
+
+       return &surface->base;
+}
+
+static void r600_surface_destroy(struct pipe_context *pipe,
+                                struct pipe_surface *surface)
+{
+       pipe_resource_reference(&surface->texture, NULL);
+       FREE(surface);
+}
+
+static boolean si_dma_copy(struct pipe_context *ctx,
+                          struct pipe_resource *dst,
+                          unsigned dst_level,
+                          unsigned dst_x, unsigned dst_y, unsigned dst_z,
+                          struct pipe_resource *src,
+                          unsigned src_level,
+                          const struct pipe_box *src_box)
+{
+       /* XXX implement this or share evergreen_dma_blit with r600g */
+       return FALSE;
+}
+
 void si_init_state_functions(struct r600_context *rctx)
 {
        int i;
@@ -2960,13 +3021,11 @@ void si_init_state_functions(struct r600_context *rctx)
        rctx->b.b.delete_fs_state = si_delete_ps_shader;
 
        rctx->b.b.create_sampler_state = si_create_sampler_state;
-       rctx->b.b.bind_vertex_sampler_states = si_bind_vs_sampler_states;
-       rctx->b.b.bind_fragment_sampler_states = si_bind_ps_sampler_states;
+       rctx->b.b.bind_sampler_states = si_bind_sampler_states;
        rctx->b.b.delete_sampler_state = si_delete_sampler_state;
 
        rctx->b.b.create_sampler_view = si_create_sampler_view;
-       rctx->b.b.set_vertex_sampler_views = si_set_vs_sampler_views;
-       rctx->b.b.set_fragment_sampler_views = si_set_ps_sampler_views;
+       rctx->b.b.set_sampler_views = si_set_sampler_views;
        rctx->b.b.sampler_view_destroy = si_sampler_view_destroy;
 
        rctx->b.b.set_sample_mask = si_set_sample_mask;
@@ -2979,6 +3038,9 @@ void si_init_state_functions(struct r600_context *rctx)
 
        rctx->b.b.texture_barrier = si_texture_barrier;
        rctx->b.b.set_polygon_stipple = si_set_polygon_stipple;
+       rctx->b.b.create_surface = r600_create_surface;
+       rctx->b.b.surface_destroy = r600_surface_destroy;
+       rctx->b.dma_copy = si_dma_copy;
 
        rctx->b.b.draw_vbo = si_draw_vbo;
 }
@@ -3012,10 +3074,12 @@ void si_init_config(struct r600_context *rctx)
        si_pm4_set_reg(pm4, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
        si_pm4_set_reg(pm4, R_028B94_VGT_STRMOUT_CONFIG, 0x0);
        si_pm4_set_reg(pm4, R_028B98_VGT_STRMOUT_BUFFER_CONFIG, 0x0);
-       si_pm4_set_reg(pm4, R_028AA8_IA_MULTI_VGT_PARAM,
-                      S_028AA8_SWITCH_ON_EOP(1) |
-                      S_028AA8_PARTIAL_VS_WAVE_ON(1) |
-                      S_028AA8_PRIMGROUP_SIZE(63));
+       if (rctx->b.chip_class == SI) {
+               si_pm4_set_reg(pm4, R_028AA8_IA_MULTI_VGT_PARAM,
+                              S_028AA8_SWITCH_ON_EOP(1) |
+                              S_028AA8_PARTIAL_VS_WAVE_ON(1) |
+                              S_028AA8_PRIMGROUP_SIZE(63));
+       }
        si_pm4_set_reg(pm4, R_028AB4_VGT_REUSE_OFF, 0x00000000);
        si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0x0);
        if (rctx->b.chip_class < CIK)