r600/sb: handle lds special dest registers.
[mesa.git] / src / gallium / drivers / r600 / r600_state.c
index fc93eb02ad2b141ed2a62cbbd825bed77d4f80a7..89cf7d2e50ae545becd48e528d7646aa6b09f551 100644 (file)
@@ -817,7 +817,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
        unsigned offset;
        const struct util_format_description *desc;
        int i;
-       bool blend_bypass = 0, blend_clamp = 1, do_endian_swap = FALSE;
+       bool blend_bypass = 0, blend_clamp = 0, do_endian_swap = FALSE;
 
        if (rtex->db_compatible && !r600_can_sample_zs(rtex, false)) {
                r600_init_flushed_depth_texture(&rctx->b.b, surf->base.texture, NULL);
@@ -869,6 +869,8 @@ static void r600_init_color_surface(struct r600_context *rctx,
                        ntype = V_0280A0_NUMBER_UNORM;
                else if (desc->channel[i].pure_integer)
                        ntype = V_0280A0_NUMBER_UINT;
+       } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) {
+               ntype = V_0280A0_NUMBER_FLOAT;
        }
 
        if (R600_BIG_ENDIAN)
@@ -883,6 +885,11 @@ static void r600_init_color_surface(struct r600_context *rctx,
 
        endian = r600_colorformat_endian_swap(format, do_endian_swap);
 
+       /* blend clamp should be set for all NORM/SRGB types */
+       if (ntype == V_0280A0_NUMBER_UNORM || ntype == V_0280A0_NUMBER_SNORM ||
+           ntype == V_0280A0_NUMBER_SRGB)
+               blend_clamp = 1;
+
        /* set blend bypass according to docs if SINT/UINT or
           8/24 COLOR variants */
        if (ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT ||
@@ -898,6 +905,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
                S_0280A0_COMP_SWAP(swap) |
                S_0280A0_BLEND_BYPASS(blend_bypass) |
                S_0280A0_BLEND_CLAMP(blend_clamp) |
+               S_0280A0_SIMPLE_FLOAT(1) |
                S_0280A0_NUMBER_TYPE(ntype) |
                S_0280A0_ENDIAN(endian);
 
@@ -916,6 +924,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
                     ntype != V_0280A0_NUMBER_UINT &&
                     ntype != V_0280A0_NUMBER_SINT) &&
                    G_0280A0_BLEND_CLAMP(color_info) &&
+                   /* XXX this condition is always true since BLEND_FLOAT32 is never set (bug?). */
                    !G_0280A0_BLEND_FLOAT32(color_info)) {
                        color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
                        surf->export_16bpc = true;
@@ -1060,9 +1069,8 @@ static void r600_init_depth_surface(struct r600_context *rctx,
        surf->db_depth_size = S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice);
        surf->db_prefetch_limit = (rtex->surface.u.legacy.level[level].nblk_y / 8) - 1;
 
-       /* use htile only for first level */
-       if (rtex->htile_buffer && !level) {
-               surf->db_htile_data_base = 0;
+       if (r600_htile_enabled(rtex, level)) {
+               surf->db_htile_data_base = rtex->htile_offset >> 8;
                surf->db_htile_surface = S_028D24_HTILE_WIDTH(1) |
                                         S_028D24_HTILE_HEIGHT(1) |
                                         S_028D24_FULL_CACHE(1);
@@ -1543,7 +1551,7 @@ static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom
                radeon_set_context_reg(cs, R_02802C_DB_DEPTH_CLEAR, fui(rtex->depth_clear_value));
                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->htile_buffer,
+               reloc_idx = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, &rtex->resource,
                                                  RADEON_USAGE_READWRITE, RADEON_PRIO_HTILE);
                radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
                radeon_emit(cs, reloc_idx);
@@ -1658,7 +1666,7 @@ static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom
                unsigned buffer_index = u_bit_scan(&dirty_mask);
 
                vb = &rctx->vertex_buffer_state.vb[buffer_index];
-               rbuffer = (struct r600_resource*)vb->buffer;
+               rbuffer = (struct r600_resource*)vb->buffer.resource;
                assert(rbuffer);
 
                offset = vb->buffer_offset;
@@ -1704,15 +1712,15 @@ static void r600_emit_constant_buffers(struct r600_context *rctx,
                offset = cb->buffer_offset;
 
                if (!gs_ring_buffer) {
+                       assert(buffer_index < R600_MAX_HW_CONST_BUFFERS);
                        radeon_set_context_reg(cs, reg_alu_constbuf_size + buffer_index * 4,
                                               DIV_ROUND_UP(cb->buffer_size, 256));
                        radeon_set_context_reg(cs, reg_alu_const_cache + buffer_index * 4, offset >> 8);
+                       radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
+                       radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer,
+                                                                 RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER));
                }
 
-               radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
-               radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer,
-                                                     RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER));
-
                radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0));
                radeon_emit(cs, (buffer_id_base + buffer_index) * 7);
                radeon_emit(cs, offset); /* RESOURCEi_WORD0 */
@@ -1898,6 +1906,9 @@ static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600
        struct r600_cso_state *state = (struct r600_cso_state*)a;
        struct r600_fetch_shader *shader = (struct r600_fetch_shader*)state->cso;
 
+       if (!shader)
+               return;
+
        radeon_set_context_reg(cs, R_028894_SQ_PGM_START_FS, shader->offset >> 8);
        radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
        radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, shader->buffer,
@@ -2546,6 +2557,12 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
        r600_store_context_reg_seq(cb, R_028850_SQ_PGM_RESOURCES_PS, 2);
        r600_store_value(cb, /* R_028850_SQ_PGM_RESOURCES_PS*/
                         S_028850_NUM_GPRS(rshader->bc.ngpr) |
+       /*
+        * docs are misleading about the dx10_clamp bit. This only affects
+        * instructions using CLAMP dst modifier, in which case they will
+        * return 0 with this set for a NaN (otherwise NaN).
+        */
+                        S_028850_DX10_CLAMP(1) |
                         S_028850_STACK_SIZE(rshader->bc.nstack) |
                         S_028850_UNCACHED_FIRST_INST(ufi));
        r600_store_value(cb, exports_ps); /* R_028854_SQ_PGM_EXPORTS_PS */
@@ -2595,6 +2612,7 @@ void r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
                               S_0286C4_VS_EXPORT_COUNT(nparams - 1));
        r600_store_context_reg(cb, R_028868_SQ_PGM_RESOURCES_VS,
                               S_028868_NUM_GPRS(rshader->bc.ngpr) |
+                              S_028868_DX10_CLAMP(1) |
                               S_028868_STACK_SIZE(rshader->bc.nstack));
        if (rshader->vs_position_window_space) {
                r600_store_context_reg(cb, R_028818_PA_CL_VTE_CNTL,
@@ -2679,6 +2697,7 @@ void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
 
        r600_store_context_reg(cb, R_02887C_SQ_PGM_RESOURCES_GS,
                               S_02887C_NUM_GPRS(rshader->bc.ngpr) |
+                              S_02887C_DX10_CLAMP(1) |
                               S_02887C_STACK_SIZE(rshader->bc.nstack));
        r600_store_context_reg(cb, R_02886C_SQ_PGM_START_GS, 0);
        /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
@@ -2693,6 +2712,7 @@ void r600_update_es_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
 
        r600_store_context_reg(cb, R_028890_SQ_PGM_RESOURCES_ES,
                               S_028890_NUM_GPRS(rshader->bc.ngpr) |
+                              S_028890_DX10_CLAMP(1) |
                               S_028890_STACK_SIZE(rshader->bc.nstack));
        r600_store_context_reg(cb, R_028880_SQ_PGM_START_ES, 0);
        /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
@@ -2861,7 +2881,7 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                z = src_z;
                base = rsrc->surface.u.legacy.level[src_level].offset;
                addr = rdst->surface.u.legacy.level[dst_level].offset;
-               addr += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
+               addr += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
                addr += dst_y * pitch + dst_x * bpp;
        } else {
                /* L2T */
@@ -2880,7 +2900,7 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                z = dst_z;
                base = rdst->surface.u.legacy.level[dst_level].offset;
                addr = rsrc->surface.u.legacy.level[src_level].offset;
-               addr += rsrc->surface.u.legacy.level[src_level].slice_size * src_z;
+               addr += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_z;
                addr += src_y * pitch + src_x * bpp;
        }
        /* check that we are in dw/base alignment constraint */
@@ -2985,10 +3005,10 @@ static void r600_dma_copy(struct pipe_context *ctx,
                 *   dst_pitch == src_pitch
                 */
                src_offset= rsrc->surface.u.legacy.level[src_level].offset;
-               src_offset += rsrc->surface.u.legacy.level[src_level].slice_size * src_box->z;
+               src_offset += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_box->z;
                src_offset += src_y * src_pitch + src_x * bpp;
                dst_offset = rdst->surface.u.legacy.level[dst_level].offset;
-               dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
+               dst_offset += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
                dst_offset += dst_y * dst_pitch + dst_x * bpp;
                size = src_box->height * src_pitch;
                /* must be dw aligned */