freedreno/a6xx: fix hang with large render target
[mesa.git] / src / gallium / drivers / r600 / r600_state.c
index 6ff8037d9cbeece89046b3a854acab26029c9ea7..b84aad6b7451eb1ee0e21e21fc61ab071831e1c7 100644 (file)
@@ -158,36 +158,37 @@ static bool r600_is_zs_format_supported(enum pipe_format format)
        return r600_translate_dbformat(format) != ~0U;
 }
 
-boolean r600_is_format_supported(struct pipe_screen *screen,
-                                enum pipe_format format,
-                                enum pipe_texture_target target,
-                                unsigned sample_count,
-                                unsigned usage)
+bool r600_is_format_supported(struct pipe_screen *screen,
+                             enum pipe_format format,
+                             enum pipe_texture_target target,
+                             unsigned sample_count,
+                             unsigned storage_sample_count,
+                             unsigned usage)
 {
        struct r600_screen *rscreen = (struct r600_screen*)screen;
        unsigned retval = 0;
 
        if (target >= PIPE_MAX_TEXTURE_TYPES) {
                R600_ERR("r600: unsupported texture type %d\n", target);
-               return FALSE;
+               return false;
        }
 
-       if (!util_format_is_supported(format, usage))
-               return FALSE;
+       if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
+               return false;
 
        if (sample_count > 1) {
                if (!rscreen->has_msaa)
-                       return FALSE;
+                       return false;
 
                /* R11G11B10 is broken on R6xx. */
                if (rscreen->b.chip_class == R600 &&
                    format == PIPE_FORMAT_R11G11B10_FLOAT)
-                       return FALSE;
+                       return false;
 
                /* MSAA integer colorbuffers hang. */
                if (util_format_is_pure_integer(format) &&
                    !util_format_is_depth_or_stencil(format))
-                       return FALSE;
+                       return false;
 
                switch (sample_count) {
                case 2:
@@ -195,7 +196,7 @@ boolean r600_is_format_supported(struct pipe_screen *screen,
                case 8:
                        break;
                default:
-                       return FALSE;
+                       return false;
                }
        }
 
@@ -245,7 +246,7 @@ boolean r600_is_format_supported(struct pipe_screen *screen,
 
 static void r600_emit_polygon_offset(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_poly_offset_state *state = (struct r600_poly_offset_state*)a;
        float offset_units = state->offset_units;
        float offset_scale = state->offset_scale;
@@ -478,8 +479,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
                                S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0;
        rs->pa_cl_clip_cntl =
                S_028810_DX_CLIP_SPACE_DEF(state->clip_halfz) |
-               S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
-               S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
+               S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip_near) |
+               S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip_far) |
                S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
        if (rctx->b.chip_class == R700) {
                rs->pa_cl_clip_cntl |=
@@ -519,15 +520,13 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
        }
 
        spi_interp = S_0286D4_FLAT_SHADE_ENA(1);
-       if (state->sprite_coord_enable) {
-               spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
-                             S_0286D4_PNT_SPRITE_OVRD_X(2) |
-                             S_0286D4_PNT_SPRITE_OVRD_Y(3) |
-                             S_0286D4_PNT_SPRITE_OVRD_Z(0) |
-                             S_0286D4_PNT_SPRITE_OVRD_W(1);
-               if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
-                       spi_interp |= S_0286D4_PNT_SPRITE_TOP_1(1);
-               }
+       spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
+               S_0286D4_PNT_SPRITE_OVRD_X(2) |
+               S_0286D4_PNT_SPRITE_OVRD_Y(3) |
+               S_0286D4_PNT_SPRITE_OVRD_Z(0) |
+               S_0286D4_PNT_SPRITE_OVRD_W(1);
+       if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
+               spi_interp |= S_0286D4_PNT_SPRITE_TOP_1(1);
        }
 
        r600_store_context_reg_seq(&rs->buffer, R_028A00_PA_SU_POINT_SIZE, 3);
@@ -791,7 +790,7 @@ r600_create_sampler_view(struct pipe_context *ctx,
 
 static void r600_emit_clip_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct pipe_clip_state *state = &rctx->clip_state.state;
 
        radeon_set_context_reg_seq(cs, R_028E20_PA_CL_UCP0_X, 6*4);
@@ -1088,6 +1087,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        struct r600_surface *surf;
        struct r600_texture *rtex;
        unsigned i;
+       uint32_t target_mask = 0;
 
        /* Flush TC when changing the framebuffer state, because the only
         * client not using TC that can change textures is the framebuffer.
@@ -1128,6 +1128,8 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
                rtex = (struct r600_texture*)surf->base.texture;
                r600_context_add_resource_size(ctx, state->cbufs[i]->texture);
 
+               target_mask |= (0xf << (i * 4));
+
                if (!surf->color_initialized || force_cmask_fmask) {
                        r600_init_color_surface(rctx, surf, force_cmask_fmask);
                        if (force_cmask_fmask) {
@@ -1187,7 +1189,9 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
                r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
        }
 
-       if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs) {
+       if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs ||
+           rctx->cb_misc_state.bound_cbufs_target_mask != target_mask) {
+               rctx->cb_misc_state.bound_cbufs_target_mask = target_mask;
                rctx->cb_misc_state.nr_cbufs = state->nr_cbufs;
                r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
        }
@@ -1220,22 +1224,22 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        rctx->framebuffer.do_update_surf_dirtiness = true;
 }
 
-static uint32_t sample_locs_2x[] = {
+static const uint32_t sample_locs_2x[] = {
        FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4),
        FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4),
 };
-static unsigned max_dist_2x = 4;
+static const unsigned max_dist_2x = 4;
 
-static uint32_t sample_locs_4x[] = {
+static const uint32_t sample_locs_4x[] = {
        FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6),
        FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6),
 };
-static unsigned max_dist_4x = 6;
-static uint32_t sample_locs_8x[] = {
+static const unsigned max_dist_4x = 6;
+static const uint32_t sample_locs_8x[] = {
        FILL_SREG(-1,  1,  1,  5,  3, -5,  5,  3),
        FILL_SREG(-7, -1, -3, -7,  7, -3, -5,  7),
 };
-static unsigned max_dist_8x = 7;
+static const unsigned max_dist_8x = 7;
 
 static void r600_get_sample_position(struct pipe_context *ctx,
                                     unsigned sample_count,
@@ -1278,7 +1282,7 @@ static void r600_get_sample_position(struct pipe_context *ctx,
 
 static void r600_emit_msaa_state(struct r600_context *rctx, int nr_samples)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        unsigned max_dist = 0;
 
        if (rctx->b.family == CHIP_R600) {
@@ -1345,7 +1349,7 @@ static void r600_emit_msaa_state(struct r600_context *rctx, int nr_samples)
 
 static void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct pipe_framebuffer_state *state = &rctx->framebuffer.state;
        unsigned nr_cbufs = state->nr_cbufs;
        struct r600_surface **cb = (struct r600_surface**)&state->cbufs[0];
@@ -1511,7 +1515,7 @@ static void r600_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
 
 static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_cb_misc_state *a = (struct r600_cb_misc_state*)atom;
 
        if (G_028808_SPECIAL_OP(a->cb_color_control) == V_028808_SPECIAL_RESOLVE_BOX) {
@@ -1525,7 +1529,7 @@ static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom
                }
                radeon_set_context_reg(cs, R_028808_CB_COLOR_CONTROL, a->cb_color_control);
        } else {
-               unsigned fb_colormask = (1ULL << ((unsigned)a->nr_cbufs * 4)) - 1;
+               unsigned fb_colormask = a->bound_cbufs_target_mask;
                unsigned ps_colormask = a->ps_color_export_mask;
                unsigned multiwrite = a->multiwrite && a->nr_cbufs > 1;
 
@@ -1541,7 +1545,7 @@ static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom
 
 static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_db_state *a = (struct r600_db_state*)atom;
 
        if (a->rsurf && a->rsurf->db_htile_surface) {
@@ -1552,7 +1556,7 @@ static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom
                radeon_set_context_reg(cs, R_028D24_DB_HTILE_SURFACE, a->rsurf->db_htile_surface);
                radeon_set_context_reg(cs, R_028014_DB_HTILE_DATA_BASE, a->rsurf->db_htile_data_base);
                reloc_idx = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, &rtex->resource,
-                                                 RADEON_USAGE_READWRITE, RADEON_PRIO_HTILE);
+                                                 RADEON_USAGE_READWRITE, RADEON_PRIO_SEPARATE_META);
                radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
                radeon_emit(cs, reloc_idx);
        } else {
@@ -1562,7 +1566,7 @@ static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom
 
 static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_db_misc_state *a = (struct r600_db_misc_state*)atom;
        unsigned db_render_control = 0;
        unsigned db_render_override =
@@ -1647,7 +1651,7 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom
 
 static void r600_emit_config_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_config_state *a = (struct r600_config_state*)atom;
 
        radeon_set_config_reg(cs, R_008C04_SQ_GPR_RESOURCE_MGMT_1, a->sq_gpr_resource_mgmt_1);
@@ -1656,7 +1660,7 @@ static void r600_emit_config_state(struct r600_context *rctx, struct r600_atom *
 
 static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = rctx->vertex_buffer_state.dirty_mask;
 
        while (dirty_mask) {
@@ -1696,7 +1700,7 @@ static void r600_emit_constant_buffers(struct r600_context *rctx,
                                       unsigned reg_alu_constbuf_size,
                                       unsigned reg_alu_const_cache)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = state->dirty_mask;
 
        while (dirty_mask) {
@@ -1724,7 +1728,7 @@ static void r600_emit_constant_buffers(struct r600_context *rctx,
                radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0));
                radeon_emit(cs, (buffer_id_base + buffer_index) * 7);
                radeon_emit(cs, offset); /* RESOURCEi_WORD0 */
-               radeon_emit(cs, rbuffer->b.b.width0 - offset - 1); /* RESOURCEi_WORD1 */
+               radeon_emit(cs, cb->buffer_size - 1); /* RESOURCEi_WORD1 */
                radeon_emit(cs, /* RESOURCEi_WORD2 */
                            S_038008_ENDIAN_SWAP(gs_ring_buffer ? ENDIAN_NONE : r600_endian_swap(32)) |
                            S_038008_STRIDE(gs_ring_buffer ? 4 : 16));
@@ -1770,7 +1774,7 @@ static void r600_emit_sampler_views(struct r600_context *rctx,
                                    struct r600_samplerview_state *state,
                                    unsigned resource_id_base)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = state->dirty_mask;
 
        while (dirty_mask) {
@@ -1817,7 +1821,7 @@ static void r600_emit_sampler_states(struct r600_context *rctx,
                                unsigned resource_id_base,
                                unsigned border_color_reg)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = texinfo->states.dirty_mask;
 
        while (dirty_mask) {
@@ -1831,18 +1835,17 @@ static void r600_emit_sampler_states(struct r600_context *rctx,
 
                /* TEX_ARRAY_OVERRIDE must be set for array textures to disable
                 * filtering between layers.
-                * Don't update TEX_ARRAY_OVERRIDE if we don't have the sampler view.
                 */
-               if (rview) {
-                       enum pipe_texture_target target = rview->base.texture->target;
-                       if (target == PIPE_TEXTURE_1D_ARRAY ||
-                           target == PIPE_TEXTURE_2D_ARRAY) {
-                               rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1);
-                               texinfo->is_array_sampler[i] = true;
-                       } else {
-                               rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE;
-                               texinfo->is_array_sampler[i] = false;
-                       }
+               enum pipe_texture_target target = PIPE_BUFFER;
+               if (rview)
+                       target = rview->base.texture->target;
+               if (target == PIPE_TEXTURE_1D_ARRAY ||
+                   target == PIPE_TEXTURE_2D_ARRAY) {
+                       rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1);
+                       texinfo->is_array_sampler[i] = true;
+               } else {
+                       rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE;
+                       texinfo->is_array_sampler[i] = false;
                }
 
                radeon_emit(cs, PKT3(PKT3_SET_SAMPLER, 3, 0));
@@ -1878,7 +1881,7 @@ static void r600_emit_ps_sampler_states(struct r600_context *rctx, struct r600_a
 
 static void r600_emit_seamless_cube_map(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        unsigned tmp;
 
        tmp = S_009508_DISABLE_CUBE_ANISO(1) |
@@ -1902,7 +1905,7 @@ static void r600_emit_sample_mask(struct r600_context *rctx, struct r600_atom *a
 
 static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_cso_state *state = (struct r600_cso_state*)a;
        struct r600_fetch_shader *shader = (struct r600_fetch_shader*)state->cso;
 
@@ -1918,7 +1921,7 @@ static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600
 
 static void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_shader_stages_state *state = (struct r600_shader_stages_state*)a;
 
        uint32_t v2 = 0, primid = 0;
@@ -1953,7 +1956,7 @@ static void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom
 
 static void r600_emit_gs_rings(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_gs_rings_state *state = (struct r600_gs_rings_state*)a;
        struct r600_resource *rbuffer;
 
@@ -2469,8 +2472,9 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
                                rctx->rasterizer && rctx->rasterizer->flatshade))
                        tmp |= S_028644_FLAT_SHADE(1);
 
-               if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
-                   sprite_coord_enable & (1 << rshader->input[i].sid)) {
+               if (rshader->input[i].name == TGSI_SEMANTIC_PCOORD ||
+                   (rshader->input[i].name == TGSI_SEMANTIC_TEXCOORD &&
+                    sprite_coord_enable & (1 << rshader->input[i].sid))) {
                        tmp |= S_028644_PT_SPRITE_TEX(1);
                }
 
@@ -2520,6 +2524,7 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
        }
 
        shader->nr_ps_color_outputs = num_cout;
+       shader->ps_color_export_mask = rshader->ps_color_export_mask;
 
        spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) |
                                S_0286CC_PERSP_GRADIENT_ENA(1)|
@@ -2849,7 +2854,7 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                                unsigned pitch,
                                unsigned bpp)
 {
-       struct radeon_winsys_cs *cs = rctx->b.dma.cs;
+       struct radeon_cmdbuf *cs = rctx->b.dma.cs;
        struct r600_texture *rsrc = (struct r600_texture*)src;
        struct r600_texture *rdst = (struct r600_texture*)dst;
        unsigned array_mode, lbpp, pitch_tile_max, slice_tile_max, size;
@@ -2919,10 +2924,8 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                cheight = cheight > copy_height ? copy_height : cheight;
                size = (cheight * pitch) / 4;
                /* emit reloc before writing cs so that cs is always in consistent state */
-               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rsrc->resource, RADEON_USAGE_READ,
-                                     RADEON_PRIO_SDMA_TEXTURE);
-               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rdst->resource, RADEON_USAGE_WRITE,
-                                     RADEON_PRIO_SDMA_TEXTURE);
+               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rsrc->resource, RADEON_USAGE_READ, 0);
+               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rdst->resource, RADEON_USAGE_WRITE, 0);
                radeon_emit(cs, DMA_PACKET(DMA_PACKET_COPY, 1, 0, size));
                radeon_emit(cs, base >> 8);
                radeon_emit(cs, (detile << 31) | (array_mode << 27) |