r600g: Move fetch shader register setup to r600_state.c / evergreen_state.c.
[mesa.git] / src / gallium / drivers / r600 / evergreen_state.c
index fa239a816b530d988cd9e57505f192368476d6db..812795fd29b486d03b09cd16e2bca035dc311cc8 100644 (file)
@@ -103,7 +103,7 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx,
        }
        blend->cb_target_mask = target_mask;
        r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL,
-                               color_control, 0xFFFFFFFF, NULL);
+                               color_control, 0xFFFFFFFD, NULL);
        r600_pipe_state_add_reg(rstate, R_028C3C_PA_SC_AA_MASK, 0xFFFFFFFF, 0xFFFFFFFF, NULL);
 
        for (int i = 0; i < 8; i++) {
@@ -305,11 +305,16 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
 {
        struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
        union util_color uc;
+       uint32_t coord_trunc = 0;
 
        if (rstate == NULL) {
                return NULL;
        }
 
+       if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) ||
+           (state->min_img_filter == PIPE_TEX_FILTER_NEAREST))
+               coord_trunc = 1;
+
        rstate->id = R600_PIPE_STATE_SAMPLER;
        util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
        r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@@ -328,6 +333,7 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
                        0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0,
                                S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) |
+                               S_03C008_MC_COORD_TRUNCATE(coord_trunc) |
                                S_03C008_TYPE(1),
                                0xFFFFFFFF, NULL);
 
@@ -351,7 +357,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        struct r600_resource *rbuffer;
        unsigned format;
        uint32_t word4 = 0, yuv_format = 0, pitch = 0;
-       unsigned char swizzle[4];
+       unsigned char swizzle[4], array_mode = 0, tile_type = 0;
        struct r600_bo *bo[2];
 
        if (resource == NULL)
@@ -370,7 +376,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        swizzle[1] = state->swizzle_g;
        swizzle[2] = state->swizzle_b;
        swizzle[3] = state->swizzle_a;
-       format = r600_translate_texformat(state->format,
+       format = r600_translate_texformat(ctx->screen, state->format,
                                          swizzle,
                                          &word4, &yuv_format);
        if (format == ~0) {
@@ -380,35 +386,42 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        if (desc == NULL) {
                R600_ERR("unknow format %d\n", state->format);
        }
-       tmp = (struct r600_resource_texture*)texture;
+       tmp = (struct r600_resource_texture *)texture;
+       if (tmp->depth && !tmp->is_flushing_texture) {
+               r600_texture_depth_flush(ctx, texture, TRUE);
+               tmp = tmp->flushed_depth_texture;
+       }
+
+       if (tmp->force_int_type) {
+               word4 &= C_030010_NUM_FORMAT_ALL;
+               word4 |= S_030010_NUM_FORMAT_ALL(V_030010_SQ_NUM_FORMAT_INT);
+       }
+
        rbuffer = &tmp->resource;
        bo[0] = rbuffer->bo;
        bo[1] = rbuffer->bo;
-       /* FIXME depth texture decompression */
-       if (tmp->depth) {
-               r600_texture_depth_flush(ctx, texture);
-               tmp = (struct r600_resource_texture*)texture;
-               rbuffer = &tmp->flushed_depth_texture->resource;
-               bo[0] = rbuffer->bo;
-               bo[1] = rbuffer->bo;
-       }
-       pitch = align(tmp->pitch_in_pixels[0], 8);
+
+       pitch = align(tmp->pitch_in_blocks[0] * util_format_get_blockwidth(state->format), 8);
+       array_mode = tmp->array_mode[0];
+       tile_type = tmp->tile_type;
 
        /* FIXME properly handle first level != 0 */
        r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
                                S_030000_DIM(r600_tex_dim(texture->target)) |
                                S_030000_PITCH((pitch / 8) - 1) |
+                               S_030000_NON_DISP_TILING_ORDER(tile_type) |
                                S_030000_TEX_WIDTH(texture->width0 - 1), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
                                S_030004_TEX_HEIGHT(texture->height0 - 1) |
-                               S_030004_TEX_DEPTH(texture->depth0 - 1),
+                               S_030004_TEX_DEPTH(texture->depth0 - 1) |
+                               S_030004_ARRAY_MODE(array_mode),
                                0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2,
                                (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
        r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3,
                                (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8, 0xFFFFFFFF, bo[1]);
        r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4,
-                               word4 | S_030010_NUM_FORMAT_ALL(V_030010_SQ_NUM_FORMAT_NORM) |
+                               word4 |
                                S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_NO_ZERO) |
                                S_030010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5,
@@ -431,7 +444,8 @@ static void evergreen_set_vs_sampler_view(struct pipe_context *ctx, unsigned cou
 
        for (int i = 0; i < count; i++) {
                if (resource[i]) {
-                       evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, i);
+                       evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state,
+                                                                    i + R600_MAX_CONST_BUFFERS);
                }
        }
 }
@@ -446,9 +460,11 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou
        for (i = 0; i < count; i++) {
                if (&rctx->ps_samplers.views[i]->base != views[i]) {
                        if (resource[i])
-                               evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, &resource[i]->state, i);
+                               evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, &resource[i]->state,
+                                                                            i + R600_MAX_CONST_BUFFERS);
                        else
-                               evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, NULL, i);
+                               evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, NULL,
+                                                                            i + R600_MAX_CONST_BUFFERS);
 
                        pipe_sampler_view_reference(
                                (struct pipe_sampler_view **)&rctx->ps_samplers.views[i],
@@ -457,7 +473,8 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou
        }
        for (i = count; i < NUM_TEX_UNITS; i++) {
                if (rctx->ps_samplers.views[i]) {
-                       evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, NULL, i);
+                       evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, NULL,
+                                                                    i + R600_MAX_CONST_BUFFERS);
                        pipe_sampler_view_reference((struct pipe_sampler_view **)&rctx->ps_samplers.views[i], NULL);
                }
        }
@@ -638,11 +655,19 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
        unsigned color_info;
        unsigned format, swap, ntype;
        unsigned offset;
+       unsigned tile_type;
        const struct util_format_description *desc;
        struct r600_bo *bo[3];
+       int i;
 
        surf = (struct r600_surface *)state->cbufs[cb];
        rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
+
+       if (rtex->depth && !rtex->is_flushing_texture) {
+               r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE);
+               rtex = rtex->flushed_depth_texture;
+       }
+
        rbuffer = &rtex->resource;
        bo[0] = rbuffer->bo;
        bo[1] = rbuffer->bo;
@@ -651,21 +676,43 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
        /* XXX quite sure for dx10+ hw don't need any offset hacks */
        offset = r600_texture_get_offset((struct r600_resource_texture *)state->cbufs[cb]->texture,
                                         level, state->cbufs[cb]->u.tex.first_layer);
-       pitch = rtex->pitch_in_pixels[level] / 8 - 1;
-       slice = rtex->pitch_in_pixels[level] * surf->aligned_height / 64 - 1;
+       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
        ntype = 0;
-       desc = util_format_description(rtex->resource.base.b.format);
+       desc = util_format_description(surf->base.format);
        if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
                ntype = V_028C70_NUMBER_SRGB;
 
-       format = r600_translate_colorformat(rtex->resource.base.b.format);
-       swap = r600_translate_colorswap(rtex->resource.base.b.format);
+       format = r600_translate_colorformat(surf->base.format);
+       swap = r600_translate_colorswap(surf->base.format);
+
+       /* disable when gallium grows int textures */
+       if ((format == FMT_32_32_32_32 || format == FMT_16_16_16_16) && rtex->force_int_type)
+               ntype = 4;
+
        color_info = S_028C70_FORMAT(format) |
                S_028C70_COMP_SWAP(swap) |
+               S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
                S_028C70_BLEND_CLAMP(1) |
                S_028C70_NUMBER_TYPE(ntype);
-       if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
-               color_info |= S_028C70_SOURCE_FORMAT(1);
+
+       for (i = 0; i < 4; i++) {
+               if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+                       break;
+               }
+       }
+
+       /* we can only set the export size if any thing is snorm/unorm component is > 11 bits,
+          if we aren't a float, sint or uint */
+       if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
+           desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
+           ntype != 4 && ntype != 5)
+               color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
+
+       if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) {
+               tile_type = rtex->tile_type;
+       } else /* workaround for linear buffers */
+               tile_type = 1;
 
        /* FIXME handle enabling of CB beyond BASE8 which has different offset */
        r600_pipe_state_add_reg(rstate,
@@ -690,7 +737,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
                                0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate,
                                R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
-                               S_028C74_NON_DISP_TILING_ORDER(1),
+                               S_028C74_NON_DISP_TILING_ORDER(tile_type),
                                0xFFFFFFFF, bo[0]);
 }
 
@@ -711,17 +758,14 @@ static void evergreen_db(struct r600_pipe_context *rctx, struct r600_pipe_state
 
        surf = (struct r600_surface *)state->zsbuf;
        rtex = (struct r600_resource_texture*)state->zsbuf->texture;
-       rtex->tiled = 1;
-       rtex->array_mode[level] = 2;
-       rtex->tile_type = 1;
-       rtex->depth = 1;
+
        rbuffer = &rtex->resource;
 
        /* XXX quite sure for dx10+ hw don't need any offset hacks */
        offset = r600_texture_get_offset((struct r600_resource_texture *)state->zsbuf->texture,
                                         level, state->zsbuf->u.tex.first_layer);
-       pitch = rtex->pitch_in_pixels[level] / 8 - 1;
-       slice = rtex->pitch_in_pixels[level] * surf->aligned_height / 64 - 1;
+       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
        format = r600_translate_dbformat(state->zsbuf->texture->format);
        stencil_format = r600_translate_stencilformat(state->zsbuf->texture->format);
 
@@ -876,6 +920,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx)
        rctx->context.set_vertex_sampler_views = evergreen_set_vs_sampler_view;
        rctx->context.set_viewport_state = evergreen_set_viewport_state;
        rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
+       rctx->context.redefine_user_buffer = u_default_redefine_user_buffer;
 }
 
 void evergreen_init_config(struct r600_pipe_context *rctx)
@@ -1456,6 +1501,18 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader
                                0xFFFFFFFF, NULL);
 }
 
+void evergreen_fetch_shader(struct r600_vertex_element *ve)
+{
+       struct r600_pipe_state *rstate = &ve->rstate;
+       rstate->id = R600_PIPE_STATE_FETCH_SHADER;
+       rstate->nregs = 0;
+       r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS,
+                               0x00000000, 0xFFFFFFFF, NULL);
+       r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS,
+                               (r600_bo_offset(ve->fetch_shader)) >> 8,
+                               0xFFFFFFFF, ve->fetch_shader);
+}
+
 void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx)
 {
        struct pipe_depth_stencil_alpha_state dsa;
@@ -1479,11 +1536,10 @@ void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx)
        return rstate;
 }
 
-void evergreen_pipe_add_vertex_attrib(struct r600_pipe_context *rctx,
-                                     struct r600_pipe_state *rstate,
-                                     unsigned index,
-                                     struct r600_resource *rbuffer,
-                                     unsigned offset, unsigned stride)
+void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
+                                       struct r600_pipe_state *rstate,
+                                       struct r600_resource *rbuffer,
+                                       unsigned offset, unsigned stride)
 {
        r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
                                offset, 0xFFFFFFFF, rbuffer->bo);
@@ -1506,5 +1562,4 @@ void evergreen_pipe_add_vertex_attrib(struct r600_pipe_context *rctx,
                                0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7,
                                0xC0000000, 0xFFFFFFFF, NULL);
-       evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, index);
 }