diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c index 57ebbb05bcb..35cd639c214 100644 --- a/src/gallium/drivers/r600/evergreen_hw_context.c +++ b/src/gallium/drivers/r600/evergreen_hw_context.c @@ -110,12 +110,7 @@ static const struct r600_reg evergreen_context_reg_list[] = { {R_028A48_PA_SC_MODE_CNTL_0, 0, 0}, {R_028ABC_DB_HTILE_SURFACE, 0, 0}, {R_028B54_VGT_SHADER_STAGES_EN, 0, 0}, - {R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, 0, 0}, {R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0, 0}, - {R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, 0, 0}, - {R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, 0, 0}, - {R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, 0, 0}, - {R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, 0, 0}, {R_028C08_PA_SU_VTX_CNTL, 0, 0}, }; @@ -205,12 +200,7 @@ static const struct r600_reg cayman_context_reg_list[] = { {R_028A48_PA_SC_MODE_CNTL_0, 0, 0}, {R_028ABC_DB_HTILE_SURFACE, 0, 0}, {R_028B54_VGT_SHADER_STAGES_EN, 0, 0}, - {R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, 0, 0}, {R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0, 0}, - {R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, 0, 0}, - {R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, 0, 0}, - {R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, 0, 0}, - {R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, 0, 0}, {CM_R_028BE4_PA_SU_VTX_CNTL, 0, 0}, }; diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index d2bbc5be94b..4e3f2e59e93 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -871,6 +871,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, /* offset */ rs->offset_units = state->offset_units; rs->offset_scale = state->offset_scale * 12.0f; + rs->offset_enable = state->offset_point || state->offset_line || state->offset_tri; rstate->id = R600_PIPE_STATE_RASTERIZER; tmp = S_0286D4_FLAT_SHADE_ENA(1); @@ -1496,6 +1497,25 @@ static void evergreen_init_depth_surface(struct r600_context *rctx, surf->db_depth_size = S_028058_PITCH_TILE_MAX(pitch); surf->db_depth_slice = S_02805C_SLICE_TILE_MAX(slice); + switch (surf->base.format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + surf->pa_su_poly_offset_db_fmt_cntl = + S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS((char)-24); + break; + case PIPE_FORMAT_Z32_FLOAT: + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + surf->pa_su_poly_offset_db_fmt_cntl = + S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS((char)-23) | + S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1); + break; + case PIPE_FORMAT_Z16_UNORM: + surf->pa_su_poly_offset_db_fmt_cntl = + S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS((char)-16); + break; + default:; + } + if (rtex->surface.flags & RADEON_SURF_SBUFFER) { uint64_t stencil_offset = rtex->surface.stencil_offset; unsigned i, stile_split = rtex->surface.stencil_tile_split; @@ -1606,7 +1626,10 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, evergreen_init_depth_surface(rctx, surf); } - evergreen_polygon_offset_update(rctx); + if (state->zsbuf->format != rctx->poly_offset_state.zs_format) { + rctx->poly_offset_state.zs_format = state->zsbuf->format; + rctx->poly_offset_state.atom.dirty = true; + } } if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs) { @@ -1664,7 +1687,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, /* ZS buffer. */ if (state->zsbuf) { - rctx->framebuffer.atom.num_dw += 21; + rctx->framebuffer.atom.num_dw += 24; if (rctx->keep_tiling_flags) rctx->framebuffer.atom.num_dw += 2; } else if (rctx->screen->info.drm_minor >= 18) { @@ -1969,6 +1992,8 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r unsigned reloc = r600_context_bo_reloc(rctx, (struct r600_resource*)state->zsbuf->texture, RADEON_USAGE_READWRITE); + r600_write_context_reg(cs, R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, + zb->pa_su_poly_offset_db_fmt_cntl); r600_write_context_reg(cs, R_028008_DB_DEPTH_VIEW, zb->db_depth_view); r600_write_context_reg_seq(cs, R_028040_DB_Z_INFO, 8); @@ -2019,6 +2044,31 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r } } +static void evergreen_emit_polygon_offset(struct r600_context *rctx, struct r600_atom *a) +{ + struct radeon_winsys_cs *cs = rctx->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; + + switch (state->zs_format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z16_UNORM: + offset_units *= 4.0f; + break; + default:; + } + + r600_write_context_reg_seq(cs, R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, 4); + r600_write_value(cs, fui(offset_scale)); + r600_write_value(cs, fui(offset_units)); + r600_write_value(cs, fui(offset_scale)); + r600_write_value(cs, fui(offset_units)); +} + static void evergreen_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom) { struct radeon_winsys_cs *cs = rctx->cs; @@ -2370,6 +2420,7 @@ void evergreen_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->clip_misc_state.atom, id++, r600_emit_clip_misc_state, 6); r600_init_atom(rctx, &rctx->clip_state.atom, id++, evergreen_emit_clip_state, 26); r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, evergreen_emit_db_misc_state, 7); + r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, evergreen_emit_polygon_offset, 6); r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4); r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8); r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, evergreen_emit_vertex_fetch_shader, 5); @@ -3086,56 +3137,6 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx) eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF); } -void evergreen_polygon_offset_update(struct r600_context *rctx) -{ - struct r600_pipe_state state; - - state.id = R600_PIPE_STATE_POLYGON_OFFSET; - state.nregs = 0; - if (rctx->rasterizer && rctx->framebuffer.state.zsbuf) { - float offset_units = rctx->rasterizer->offset_units; - unsigned offset_db_fmt_cntl = 0, depth; - - switch (rctx->framebuffer.state.zsbuf->format) { - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - depth = -24; - offset_units *= 2.0f; - break; - case PIPE_FORMAT_Z32_FLOAT: - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - depth = -23; - offset_units *= 1.0f; - offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1); - break; - case PIPE_FORMAT_Z16_UNORM: - depth = -16; - offset_units *= 4.0f; - break; - default: - return; - } - /* XXX some of those reg can be computed with cso */ - offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth); - r600_pipe_state_add_reg(&state, - R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, - fui(rctx->rasterizer->offset_scale)); - r600_pipe_state_add_reg(&state, - R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, - fui(offset_units)); - r600_pipe_state_add_reg(&state, - R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, - fui(rctx->rasterizer->offset_scale)); - r600_pipe_state_add_reg(&state, - R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, - fui(offset_units)); - r600_pipe_state_add_reg(&state, - R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, - offset_db_fmt_cntl); - r600_context_pipe_state_set(rctx, &state); - } -} - void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader) { struct r600_context *rctx = (struct r600_context *)ctx; diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 2b260c8d94a..e624187981f 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -233,12 +233,7 @@ static const struct r600_reg r600_context_reg_list[] = { {R_028A04_PA_SU_POINT_MINMAX, 0, 0}, {R_028A08_PA_SU_LINE_CNTL, 0, 0}, {R_028C08_PA_SU_VTX_CNTL, 0, 0}, - {R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, 0, 0}, {R_028DFC_PA_SU_POLY_OFFSET_CLAMP, 0, 0}, - {R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, 0, 0}, - {R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET, 0, 0}, - {R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE, 0, 0}, - {R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET, 0, 0}, {R_028350_SX_MISC, 0, 0}, {R_028380_SQ_VTX_SEMANTIC_0, 0, 0}, {R_028384_SQ_VTX_SEMANTIC_1, 0, 0}, @@ -867,6 +862,7 @@ void r600_begin_new_cs(struct r600_context *ctx) ctx->clip_state.atom.dirty = true; ctx->db_misc_state.atom.dirty = true; ctx->framebuffer.atom.dirty = true; + ctx->poly_offset_state.atom.dirty = true; ctx->vgt_state.atom.dirty = true; ctx->vgt2_state.atom.dirty = true; ctx->sample_mask.atom.dirty = true; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index a510baf93ad..a548846beef 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -35,7 +35,7 @@ #include "r600_resource.h" #include "evergreen_compute.h" -#define R600_NUM_ATOMS 31 +#define R600_NUM_ATOMS 32 #define R600_MAX_CONST_BUFFERS 2 #define R600_MAX_CONST_BUFFER_SIZE 4096 @@ -164,7 +164,6 @@ enum r600_pipe_state_id { R600_PIPE_STATE_SCISSOR, R600_PIPE_STATE_RASTERIZER, R600_PIPE_STATE_DSA, - R600_PIPE_STATE_POLYGON_OFFSET, R600_PIPE_NSTATES }; @@ -217,10 +216,18 @@ struct r600_pipe_rasterizer { unsigned pa_cl_clip_cntl; float offset_units; float offset_scale; + bool offset_enable; bool scissor_enable; bool multisample_enable; }; +struct r600_poly_offset_state { + struct r600_atom atom; + enum pipe_format zs_format; + float offset_units; + float offset_scale; +}; + struct r600_blend_state { struct r600_command_buffer buffer; struct r600_command_buffer buffer_no_blend; @@ -411,6 +418,7 @@ struct r600_context { struct r600_clip_state clip_state; struct r600_db_misc_state db_misc_state; struct r600_framebuffer framebuffer; + struct r600_poly_offset_state poly_offset_state; struct r600_sample_mask sample_mask; struct r600_seamless_cube_map seamless_cube_map; struct r600_stencil_ref_state stencil_ref; @@ -541,7 +549,6 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader void *evergreen_create_db_flush_dsa(struct r600_context *rctx); void *evergreen_create_resolve_blend(struct r600_context *rctx); void *evergreen_create_decompress_blend(struct r600_context *rctx); -void evergreen_polygon_offset_update(struct r600_context *rctx); boolean evergreen_is_format_supported(struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, @@ -618,7 +625,6 @@ void *r600_create_db_flush_dsa(struct r600_context *rctx); void *r600_create_resolve_blend(struct r600_context *rctx); void *r700_create_resolve_blend(struct r600_context *rctx); void *r600_create_decompress_blend(struct r600_context *rctx); -void r600_polygon_offset_update(struct r600_context *rctx); void r600_adjust_gprs(struct r600_context *rctx); boolean r600_is_format_supported(struct pipe_screen *screen, enum pipe_format format, diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index a5a540439e6..bf7fffa44c5 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -112,6 +112,7 @@ struct r600_surface { unsigned db_stencil_base; /* EG only */ unsigned db_stencil_info; /* EG only */ unsigned db_prefetch_limit; /* R600 only */ + unsigned pa_su_poly_offset_db_fmt_cntl; }; void r600_resource_destroy(struct pipe_screen *screen, struct pipe_resource *res); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 0881bae612d..728fcb6d60a 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -642,54 +642,29 @@ boolean r600_is_format_supported(struct pipe_screen *screen, return retval == usage; } -void r600_polygon_offset_update(struct r600_context *rctx) +static void r600_emit_polygon_offset(struct r600_context *rctx, struct r600_atom *a) { - struct r600_pipe_state state; + struct radeon_winsys_cs *cs = rctx->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; - state.id = R600_PIPE_STATE_POLYGON_OFFSET; - state.nregs = 0; - if (rctx->rasterizer && rctx->framebuffer.state.zsbuf) { - float offset_units = rctx->rasterizer->offset_units; - unsigned offset_db_fmt_cntl = 0, depth; - - switch (rctx->framebuffer.state.zsbuf->format) { - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - depth = -24; - offset_units *= 2.0f; - break; - case PIPE_FORMAT_Z32_FLOAT: - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - depth = -23; - offset_units *= 1.0f; - offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1); - break; - case PIPE_FORMAT_Z16_UNORM: - depth = -16; - offset_units *= 4.0f; - break; - default: - return; - } - /* XXX some of those reg can be computed with cso */ - offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth); - r600_pipe_state_add_reg(&state, - R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, - fui(rctx->rasterizer->offset_scale)); - r600_pipe_state_add_reg(&state, - R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET, - fui(offset_units)); - r600_pipe_state_add_reg(&state, - R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE, - fui(rctx->rasterizer->offset_scale)); - r600_pipe_state_add_reg(&state, - R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET, - fui(offset_units)); - r600_pipe_state_add_reg(&state, - R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, - offset_db_fmt_cntl); - r600_context_pipe_state_set(rctx, &state); + switch (state->zs_format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z16_UNORM: + offset_units *= 4.0f; + break; + default:; } + + r600_write_context_reg_seq(cs, R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, 4); + r600_write_value(cs, fui(offset_scale)); + r600_write_value(cs, fui(offset_units)); + r600_write_value(cs, fui(offset_scale)); + r600_write_value(cs, fui(offset_units)); } static uint32_t r600_get_blend_control(const struct pipe_blend_state *state, unsigned i) @@ -904,6 +879,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx, /* offset */ rs->offset_units = state->offset_units; rs->offset_scale = state->offset_scale * 12.0f; + rs->offset_enable = state->offset_point || state->offset_line || state->offset_tri; rstate->id = R600_PIPE_STATE_RASTERIZER; tmp = S_0286D4_FLAT_SHADE_ENA(1); @@ -1470,6 +1446,25 @@ 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.level[level].nblk_y / 8) - 1; + switch (surf->base.format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + surf->pa_su_poly_offset_db_fmt_cntl = + S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS((char)-24); + break; + case PIPE_FORMAT_Z32_FLOAT: + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + surf->pa_su_poly_offset_db_fmt_cntl = + S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS((char)-23) | + S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1); + break; + case PIPE_FORMAT_Z16_UNORM: + surf->pa_su_poly_offset_db_fmt_cntl = + S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS((char)-16); + break; + default:; + } + surf->depth_initialized = true; } @@ -1560,7 +1555,10 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, r600_init_depth_surface(rctx, surf); } - r600_polygon_offset_update(rctx); + if (state->zsbuf->format != rctx->poly_offset_state.zs_format) { + rctx->poly_offset_state.zs_format = state->zsbuf->format; + rctx->poly_offset_state.atom.dirty = true; + } } if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs) { @@ -1583,7 +1581,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, } if (rctx->framebuffer.state.zsbuf) { - rctx->framebuffer.atom.num_dw += 13; + rctx->framebuffer.atom.num_dw += 16; } else if (rctx->screen->info.drm_minor >= 18) { rctx->framebuffer.atom.num_dw += 3; } @@ -1774,6 +1772,9 @@ static void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_a (struct r600_resource*)state->zsbuf->texture, RADEON_USAGE_READWRITE); + r600_write_context_reg(cs, R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, + surf->pa_su_poly_offset_db_fmt_cntl); + r600_write_context_reg_seq(cs, R_028000_DB_DEPTH_SIZE, 2); r600_write_value(cs, surf->db_depth_size); /* R_028000_DB_DEPTH_SIZE */ r600_write_value(cs, surf->db_depth_view); /* R_028004_DB_DEPTH_VIEW */ @@ -2181,6 +2182,7 @@ void r600_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->clip_misc_state.atom, id++, r600_emit_clip_misc_state, 6); r600_init_atom(rctx, &rctx->clip_state.atom, id++, r600_emit_clip_state, 26); r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, r600_emit_db_misc_state, 4); + r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, r600_emit_polygon_offset, 6); r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4); r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8); r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, r600_emit_vertex_fetch_shader, 5); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index fe800f25a51..e30ec3dae7d 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -328,10 +328,12 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state) rctx->states[rs->rstate.id] = &rs->rstate; r600_context_pipe_state_set(rctx, &rs->rstate); - if (rctx->chip_class >= EVERGREEN) { - evergreen_polygon_offset_update(rctx); - } else { - r600_polygon_offset_update(rctx); + if (rs->offset_enable && + (rs->offset_units != rctx->poly_offset_state.offset_units || + rs->offset_scale != rctx->poly_offset_state.offset_scale)) { + rctx->poly_offset_state.offset_units = rs->offset_units; + rctx->poly_offset_state.offset_scale = rs->offset_scale; + rctx->poly_offset_state.atom.dirty = true; } /* Update clip_misc_state. */