From 58c243905b0cfcbf1b0299a0f7f0ea90755e36cc Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 24 Sep 2010 21:34:56 -0400 Subject: [PATCH] r600g: fix vertex resource & polygon offset Signed-off-by: Jerome Glisse --- src/gallium/drivers/r600/evergreen_state.c | 78 ++++++++++++++++----- src/gallium/drivers/r600/r600_pipe.h | 4 ++ src/gallium/drivers/r600/r600_state2.c | 79 +++++++++++++++++----- 3 files changed, 127 insertions(+), 34 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 4b7c251e5e9..c54b78aa6f0 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -242,8 +242,6 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, { struct r600_pipe_rasterizer *rs = CALLOC_STRUCT(r600_pipe_rasterizer); struct r600_pipe_state *rstate; - float offset_units = 0, offset_scale = 0; - unsigned offset_db_fmt_cntl = 0; unsigned tmp; unsigned prov_vtx = 1; @@ -255,6 +253,10 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, rs->flatshade = state->flatshade; rs->sprite_coord_enable = state->sprite_coord_enable; + /* offset */ + rs->offset_units = state->offset_units; + rs->offset_scale = state->offset_scale * 12.0f; + rstate->id = R600_PIPE_STATE_RASTERIZER; if (state->flatshade_first) prov_vtx = 0; @@ -293,11 +295,6 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028C18_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, offset_db_fmt_cntl, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, fui(offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, fui(offset_units), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, fui(offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, fui(offset_units), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_CONTEXT, R_028C08_PA_SU_VTX_CNTL, 0x00000005, 0xFFFFFFFF, NULL); return rstate; @@ -311,14 +308,9 @@ static void evergreen_bind_rs_state(struct pipe_context *ctx, void *state) if (state == NULL) return; - if (rctx->flatshade != rs->flatshade) { -// rctx->ps_rebuild = TRUE; - } - if (rctx->sprite_coord_enable != rs->sprite_coord_enable) { -// rctx->ps_rebuild = TRUE; - } rctx->flatshade = rs->flatshade; rctx->sprite_coord_enable = rs->sprite_coord_enable; + rctx->rasterizer = rs; rctx->states[rs->rstate.id] = &rs->rstate; r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); @@ -329,6 +321,9 @@ static void evergreen_delete_rs_state(struct pipe_context *ctx, void *state) struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; + if (rctx->rasterizer == rs) { + rctx->rasterizer = NULL; + } if (rctx->states[rs->rstate.id] == &rs->rstate) { rctx->states[rs->rstate.id] = NULL; } @@ -924,6 +919,8 @@ static void evergreen_set_vertex_buffers(struct pipe_context *ctx, unsigned coun memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); for (int i = 0; i < count; i++) { rctx->vertex_buffer[i].buffer = NULL; + if (r600_buffer_is_user_buffer(buffers[i].buffer)) + rctx->any_user_vbs = TRUE; pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer); } rctx->nvertex_buffer = count; @@ -1342,6 +1339,11 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) assert(info->index_bias == 0); + if (rctx->any_user_vbs) { + r600_upload_user_buffers2(rctx); + rctx->any_user_vbs = FALSE; + } + memset(&draw, 0, sizeof(struct r600_drawl)); draw.mode = info->mode; draw.start = info->start; @@ -1369,9 +1371,6 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) draw.index_bias = info->start; } - /* flush upload buffers */ - r600_upload_user_buffers2(rctx); - switch (draw.index_size) { case 2: vgt_draw_initiator = 0; @@ -1399,6 +1398,8 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) return; for (i = 0 ; i < rctx->vertex_elements->count; i++) { + unsigned num_format = 0, format_comp = 0; + rstate = &rctx->vs_resource[i]; j = rctx->vertex_elements->elements[i].vertex_buffer_index; vertex_buffer = &rctx->vertex_buffer[j]; @@ -1408,12 +1409,15 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) rstate->id = R600_PIPE_STATE_RESOURCE; rstate->nregs = 0; + r600_translate_vertex_num_format(rctx->vertex_elements->elements[i].src_format, &num_format, &format_comp); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_RESOURCE, R_030000_RESOURCE0_WORD0, offset, 0xFFFFFFFF, rbuffer->bo); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_RESOURCE, R_030004_RESOURCE0_WORD1, rbuffer->size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_RESOURCE, R_030008_RESOURCE0_WORD2, S_030008_STRIDE(vertex_buffer->stride) | - S_030008_DATA_FORMAT(format), + S_030008_DATA_FORMAT(format) | + S_030008_NUM_FORMAT_ALL(num_format) | + S_030008_FORMAT_COMP_ALL(format_comp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, EVERGREEN_GROUP_RESOURCE, R_03000C_RESOURCE0_WORD3, @@ -1441,6 +1445,46 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) r600_pipe_state_add_reg(&vgt, EVERGREEN_GROUP_CONTEXT, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, EVERGREEN_GROUP_CONTEXT, R_028400_VGT_MAX_VTX_INDX, draw.max_index, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, EVERGREEN_GROUP_CONTEXT, R_028404_VGT_MIN_VTX_INDX, draw.min_index, 0xFFFFFFFF, NULL); + + if (rctx->rasterizer && rctx->framebuffer.zsbuf) { + float offset_units = rctx->rasterizer->offset_units; + unsigned offset_db_fmt_cntl = 0, depth; + + switch (rctx->framebuffer.zsbuf->texture->format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + depth = -24; + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z32_FLOAT: + 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; + } + offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, + offset_db_fmt_cntl, 0xFFFFFFFF, NULL); + } r600_context_pipe_state_set(&rctx->ctx, &vgt); rdraw.vgt_num_indices = draw.count; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index e05a14f4e93..19cfbccf4f1 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -60,6 +60,8 @@ struct r600_pipe_rasterizer { struct r600_pipe_state rstate; bool flatshade; unsigned sprite_coord_enable; + float offset_units; + float offset_scale; }; struct r600_pipe_blend { @@ -108,12 +110,14 @@ struct r600_pipe_context { struct r600_pipe_shader *vs_shader; struct r600_pipe_state vs_const_buffer; struct r600_pipe_state ps_const_buffer; + struct r600_pipe_rasterizer *rasterizer; /* shader information */ unsigned sprite_coord_enable; bool flatshade; struct u_upload_mgr *upload_vb; struct u_upload_mgr *upload_ib; enum radeon_family family; + unsigned any_user_vbs; }; struct r600_drawl { diff --git a/src/gallium/drivers/r600/r600_state2.c b/src/gallium/drivers/r600/r600_state2.c index 40038f0732e..c4e06a5f528 100644 --- a/src/gallium/drivers/r600/r600_state2.c +++ b/src/gallium/drivers/r600/r600_state2.c @@ -463,9 +463,6 @@ static void r600_draw_common(struct r600_drawl *draw) struct r600_draw rdraw; struct r600_pipe_state vgt; - /* flush upload buffers */ - r600_upload_user_buffers2(rctx); - switch (draw->index_size) { case 2: vgt_draw_initiator = 0; @@ -486,6 +483,7 @@ static void r600_draw_common(struct r600_drawl *draw) if (r600_conv_pipe_prim(draw->mode, &prim)) return; + /* rebuild vertex shader if input format changed */ if (r600_pipe_shader_update2(&rctx->context, rctx->vs_shader)) return; @@ -493,6 +491,8 @@ static void r600_draw_common(struct r600_drawl *draw) return; for (i = 0 ; i < rctx->vertex_elements->count; i++) { + unsigned num_format = 0, format_comp = 0; + rstate = &rctx->vs_resource[i]; j = rctx->vertex_elements->elements[i].vertex_buffer_index; vertex_buffer = &rctx->vertex_buffer[j]; @@ -502,12 +502,15 @@ static void r600_draw_common(struct r600_drawl *draw) rstate->id = R600_PIPE_STATE_RESOURCE; rstate->nregs = 0; + r600_translate_vertex_num_format(rctx->vertex_elements->elements[i].src_format, &num_format, &format_comp); r600_pipe_state_add_reg(rstate, R600_GROUP_RESOURCE, R_038000_RESOURCE0_WORD0, offset, 0xFFFFFFFF, rbuffer->bo); r600_pipe_state_add_reg(rstate, R600_GROUP_RESOURCE, R_038004_RESOURCE0_WORD1, rbuffer->size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_RESOURCE, R_038008_RESOURCE0_WORD2, S_038008_STRIDE(vertex_buffer->stride) | - S_038008_DATA_FORMAT(format), + S_038008_DATA_FORMAT(format) | + S_038008_NUM_FORMAT_ALL(num_format) | + S_038008_FORMAT_COMP_ALL(format_comp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_RESOURCE, R_03800C_RESOURCE0_WORD3, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_RESOURCE, R_038010_RESOURCE0_WORD4, 0x00000000, 0xFFFFFFFF, NULL); @@ -528,6 +531,46 @@ static void r600_draw_common(struct r600_drawl *draw) r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, R_028400_VGT_MAX_VTX_INDX, draw->max_index, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, R_028404_VGT_MIN_VTX_INDX, draw->min_index, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL); + /* build late state */ + if (rctx->rasterizer && rctx->framebuffer.zsbuf) { + float offset_units = rctx->rasterizer->offset_units; + unsigned offset_db_fmt_cntl = 0, depth; + + switch (rctx->framebuffer.zsbuf->texture->format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + depth = -24; + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z32_FLOAT: + 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; + } + offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, + R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, + offset_db_fmt_cntl, 0xFFFFFFFF, NULL); + } r600_context_pipe_state_set(&rctx->ctx, &vgt); rdraw.vgt_num_indices = draw->count; @@ -574,6 +617,11 @@ static void r600_draw_vbo2(struct pipe_context *ctx, const struct pipe_draw_info assert(info->index_bias == 0); + if (rctx->any_user_vbs) { + r600_upload_user_buffers2(rctx); + rctx->any_user_vbs = FALSE; + } + memset(&draw, 0, sizeof(struct r600_drawl)); draw.ctx = ctx; draw.mode = info->mode; @@ -942,8 +990,6 @@ static void *r600_create_rs_state(struct pipe_context *ctx, { struct r600_pipe_rasterizer *rs = CALLOC_STRUCT(r600_pipe_rasterizer); struct r600_pipe_state *rstate; - float offset_units = 0, offset_scale = 0; - unsigned offset_db_fmt_cntl = 0; unsigned tmp; unsigned prov_vtx = 1; @@ -955,6 +1001,10 @@ static void *r600_create_rs_state(struct pipe_context *ctx, rs->flatshade = state->flatshade; rs->sprite_coord_enable = state->sprite_coord_enable; + /* offset */ + rs->offset_units = state->offset_units; + rs->offset_scale = state->offset_scale * 12.0f; + rstate->id = R600_PIPE_STATE_RASTERIZER; if (state->flatshade_first) prov_vtx = 0; @@ -995,12 +1045,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028C18_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, offset_db_fmt_cntl, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028DFC_PA_SU_POLY_OFFSET_CLAMP, 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, fui(offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET, fui(offset_units), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE, fui(offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET, fui(offset_units), 0xFFFFFFFF, NULL); return rstate; } @@ -1012,14 +1057,9 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state) if (state == NULL) return; - if (rctx->flatshade != rs->flatshade) { -// rctx->ps_rebuild = TRUE; - } - if (rctx->sprite_coord_enable != rs->sprite_coord_enable) { -// rctx->ps_rebuild = TRUE; - } rctx->flatshade = rs->flatshade; rctx->sprite_coord_enable = rs->sprite_coord_enable; + rctx->rasterizer = rs; rctx->states[rs->rstate.id] = &rs->rstate; r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); @@ -1030,6 +1070,9 @@ static void r600_delete_rs_state(struct pipe_context *ctx, void *state) struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; + if (rctx->rasterizer == rs) { + rctx->rasterizer = NULL; + } if (rctx->states[rs->rstate.id] == &rs->rstate) { rctx->states[rs->rstate.id] = NULL; } @@ -1636,6 +1679,8 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); for (int i = 0; i < count; i++) { rctx->vertex_buffer[i].buffer = NULL; + if (r600_buffer_is_user_buffer(buffers[i].buffer)) + rctx->any_user_vbs = TRUE; pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer); } rctx->nvertex_buffer = count; -- 2.30.2