diff options
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 30 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 13 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state2.c | 154 |
3 files changed, 173 insertions, 24 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 3170ec773e..4b7c251e5e 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1342,20 +1342,36 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) assert(info->index_bias == 0); + memset(&draw, 0, sizeof(struct r600_drawl)); draw.mode = info->mode; draw.start = info->start; draw.count = info->count; if (info->indexed && rctx->index_buffer.buffer) { + draw.min_index = info->min_index; + draw.max_index = info->max_index; + draw.index_bias = info->index_bias; + + r600_translate_index_buffer2(rctx, &rctx->index_buffer.buffer, + &rctx->index_buffer.index_size, + &draw.start, + info->count); + draw.index_size = rctx->index_buffer.index_size; draw.index_buffer = rctx->index_buffer.buffer; - assert(rctx->index_buffer.offset % - rctx->index_buffer.index_size == 0); - draw.start += rctx->index_buffer.offset / - rctx->index_buffer.index_size; + draw.index_buffer_offset = draw.start * draw.index_size; + draw.start = 0; + r600_upload_index_buffer2(rctx, &draw); } else { draw.index_size = 0; draw.index_buffer = NULL; + draw.min_index = info->min_index; + draw.max_index = info->max_index; + draw.index_bias = info->start; } + + /* flush upload buffers */ + r600_upload_user_buffers2(rctx); + switch (draw.index_size) { case 2: vgt_draw_initiator = 0; @@ -1421,10 +1437,10 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) vgt.id = R600_PIPE_STATE_VGT; vgt.nregs = 0; r600_pipe_state_add_reg(&vgt, EVERGREEN_GROUP_CONFIG, R_008958_VGT_PRIMITIVE_TYPE, prim, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, EVERGREEN_GROUP_CONTEXT, R_028408_VGT_INDX_OFFSET, draw.start, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, EVERGREEN_GROUP_CONTEXT, R_028408_VGT_INDX_OFFSET, draw.index_bias, 0xFFFFFFFF, NULL); 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, info->max_index, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, EVERGREEN_GROUP_CONTEXT, R_028404_VGT_MIN_VTX_INDX, 0x00000000, 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); 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 c64ca40490..e05a14f4e9 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -111,14 +111,21 @@ struct r600_pipe_context { /* shader information */ unsigned sprite_coord_enable; bool flatshade; + struct u_upload_mgr *upload_vb; + struct u_upload_mgr *upload_ib; + enum radeon_family family; }; struct r600_drawl { struct pipe_context *ctx; unsigned mode; + unsigned min_index; + unsigned max_index; + unsigned index_bias; unsigned start; unsigned count; unsigned index_size; + unsigned index_buffer_offset; struct pipe_resource *index_buffer; }; @@ -129,6 +136,12 @@ uint32_t r600_translate_texformat(enum pipe_format format, /* r600_state2.c */ int r600_pipe_shader_update2(struct pipe_context *ctx, struct r600_pipe_shader *shader); int r600_pipe_shader_create2(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens); +int r600_upload_index_buffer2(struct r600_pipe_context *rctx, struct r600_drawl *draw); +int r600_upload_user_buffers2(struct r600_pipe_context *rctx); +void r600_translate_index_buffer2(struct r600_pipe_context *r600, + struct pipe_resource **index_buffer, + unsigned *index_size, + unsigned *start, unsigned count); /* evergreen_state.c */ void evergreen_init_state_functions2(struct r600_pipe_context *rctx); diff --git a/src/gallium/drivers/r600/r600_state2.c b/src/gallium/drivers/r600/r600_state2.c index 2c55f073f0..482ec0de81 100644 --- a/src/gallium/drivers/r600/r600_state2.c +++ b/src/gallium/drivers/r600/r600_state2.c @@ -39,6 +39,8 @@ #include <util/u_pack_color.h> #include <util/u_memory.h> #include <util/u_inlines.h> +#include <util/u_upload_mgr.h> +#include <util/u_index_modify.h> #include <pipebuffer/pb_buffer.h> #include "r600.h" #include "r600d.h" @@ -108,7 +110,7 @@ static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shade struct r600_pipe_state *rstate = &shader->rstate; struct r600_shader *rshader = &shader->shader; unsigned i, tmp, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z; - boolean have_pos = FALSE; + boolean have_pos = FALSE, have_face = FALSE; /* clear previous register */ rstate->nregs = 0; @@ -123,6 +125,8 @@ static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shade rshader->input[i].name == TGSI_SEMANTIC_POSITION) { tmp |= S_028644_FLAT_SHADE(rshader->flat_shade); } + if (rshader->input[i].name == TGSI_SEMANTIC_FACE) + have_face = TRUE; if (rctx->sprite_coord_enable & (1 << i)) { tmp |= S_028644_PT_SPRITE_TEX(1); } @@ -153,7 +157,7 @@ static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shade spi_input_z |= 1; } r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_0286CC_SPI_PS_IN_CONTROL_0, spi_ps_in_control_0, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_0286D0_SPI_PS_IN_CONTROL_1, 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_0286D0_SPI_PS_IN_CONTROL_1, S_0286D0_FRONT_FACE_ENA(have_face), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_0286D8_SPI_INPUT_Z, spi_input_z, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028840_SQ_PGM_START_PS, @@ -459,6 +463,8 @@ 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: @@ -518,7 +524,9 @@ static void r600_draw_common(struct r600_drawl *draw) vgt.id = R600_PIPE_STATE_VGT; vgt.nregs = 0; r600_pipe_state_add_reg(&vgt, R600_GROUP_CONFIG, R_008958_VGT_PRIMITIVE_TYPE, prim, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, R_028408_VGT_INDX_OFFSET, draw->start, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&vgt, R600_GROUP_CONTEXT, R_028408_VGT_INDX_OFFSET, draw->index_bias, 0xFFFFFFFF, NULL); + 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); r600_context_pipe_state_set(&rctx->ctx, &vgt); @@ -535,6 +543,30 @@ static void r600_draw_common(struct r600_drawl *draw) r600_context_draw(&rctx->ctx, &rdraw); } +void r600_translate_index_buffer2(struct r600_pipe_context *r600, + struct pipe_resource **index_buffer, + unsigned *index_size, + unsigned *start, unsigned count) +{ + switch (*index_size) { + case 1: + util_shorten_ubyte_elts(&r600->context, index_buffer, 0, *start, count); + *index_size = 2; + *start = 0; + break; + + case 2: + if (*start % 2 != 0) { + util_rebuild_ushort_elts(&r600->context, index_buffer, 0, *start, count); + *start = 0; + } + break; + + case 4: + break; + } +} + static void r600_draw_vbo2(struct pipe_context *ctx, const struct pipe_draw_info *info) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -542,20 +574,32 @@ static void r600_draw_vbo2(struct pipe_context *ctx, const struct pipe_draw_info assert(info->index_bias == 0); + memset(&draw, 0, sizeof(struct r600_drawl)); draw.ctx = ctx; draw.mode = info->mode; draw.start = info->start; draw.count = info->count; if (info->indexed && rctx->index_buffer.buffer) { + draw.min_index = info->min_index; + draw.max_index = info->max_index; + draw.index_bias = info->index_bias; + + r600_translate_index_buffer2(rctx, &rctx->index_buffer.buffer, + &rctx->index_buffer.index_size, + &draw.start, + info->count); + draw.index_size = rctx->index_buffer.index_size; draw.index_buffer = rctx->index_buffer.buffer; - assert(rctx->index_buffer.offset % - rctx->index_buffer.index_size == 0); - draw.start += rctx->index_buffer.offset / - rctx->index_buffer.index_size; + draw.index_buffer_offset = draw.start * draw.index_size; + draw.start = 0; + r600_upload_index_buffer2(rctx, &draw); } else { draw.index_size = 0; draw.index_buffer = NULL; + draw.min_index = info->min_index; + draw.max_index = info->max_index; + draw.index_bias = info->start; } r600_draw_common(&draw); } @@ -572,6 +616,9 @@ static void r600_flush2(struct pipe_context *ctx, unsigned flags, if (!rctx->ctx.pm4_cdwords) return; + u_upload_flush(rctx->upload_vb); + u_upload_flush(rctx->upload_ib); + #if 0 sprintf(dname, "gallium-%08d.bof", dc); if (dc < 20) { @@ -591,6 +638,10 @@ static void r600_destroy_context(struct pipe_context *context) for (int i = 0; i < R600_PIPE_NSTATES; i++) { free(rctx->states[i]); } + + u_upload_destroy(rctx->upload_vb); + u_upload_destroy(rctx->upload_ib); + FREE(rctx); } @@ -1319,9 +1370,11 @@ static void r600_set_scissor_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_02820C_PA_SC_CLIPRECT_RULE, 0x0000FFFF, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, - R_028230_PA_SC_EDGERULE, 0xAAAAAAAA, - 0xFFFFFFFF, NULL); + if (rctx->family >= CHIP_RV770) { + r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, + R_028230_PA_SC_EDGERULE, 0xAAAAAAAA, + 0xFFFFFFFF, NULL); + } free(rctx->states[R600_PIPE_STATE_SCISSOR]); rctx->states[R600_PIPE_STATE_SCISSOR] = rstate; @@ -1418,7 +1471,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta state->cbufs[cb]->offset >> 8, 0xFFFFFFFF, bo[0]); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_0280A0_CB_COLOR0_INFO + cb * 4, - color_info, 0xFFFFFFFF, NULL); + color_info, 0xFFFFFFFF, bo[0]); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028060_CB_COLOR0_SIZE + cb * 4, S_028060_PITCH_TILE_MAX(pitch) | @@ -1469,7 +1522,7 @@ static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028004_DB_DEPTH_VIEW, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028010_DB_DEPTH_INFO, S_028010_ARRAY_MODE(rtex->array_mode) | S_028010_FORMAT(format), - 0xFFFFFFFF, NULL); + 0xFFFFFFFF, rbuffer->bo); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028D34_DB_PREFETCH_LIMIT, (state->zsbuf->height / 8) - 1, 0xFFFFFFFF, NULL); } @@ -1966,8 +2019,6 @@ static void r600_init_config2(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028AB8_VGT_VTX_CNT_EN, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028B20_VGT_STRMOUT_BUFFER_EN, 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028400_VGT_MAX_VTX_INDX, 0x00FFFFFF, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028404_VGT_MIN_VTX_INDX, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028A84_VGT_PRIMITIVEID_EN, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R600_GROUP_CONTEXT, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, 0x00000000, 0xFFFFFFFF, NULL); @@ -2045,6 +2096,7 @@ static struct pipe_context *r600_create_context2(struct pipe_screen *screen, voi /* Easy accessing of screen/winsys. */ rctx->screen = rscreen; rctx->radeon = rscreen->radeon; + rctx->family = r600_get_family(rctx->radeon); r600_init_blit_functions2(rctx); r600_init_query_functions2(rctx); @@ -2090,6 +2142,20 @@ static struct pipe_context *r600_create_context2(struct pipe_screen *screen, voi return NULL; } + rctx->upload_ib = u_upload_create(&rctx->context, 32 * 1024, 16, + PIPE_BIND_INDEX_BUFFER); + if (rctx->upload_ib == NULL) { + r600_destroy_context(&rctx->context); + return NULL; + } + + rctx->upload_vb = u_upload_create(&rctx->context, 128 * 1024, 16, + PIPE_BIND_VERTEX_BUFFER); + if (rctx->upload_vb == NULL) { + r600_destroy_context(&rctx->context); + return NULL; + } + rctx->blitter = util_blitter_create(&rctx->context); if (rctx->blitter == NULL) { FREE(rctx); @@ -2139,8 +2205,7 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e case PIPE_SHADER_CAP_MAX_PREDS: return 0; /* FIXME */ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: - /* TODO: support this! */ - return 0; + return 1; default: return 0; } @@ -2202,7 +2267,62 @@ struct pipe_screen *r600_screen_create2(struct radeon *radeon) rscreen->screen.context_create = r600_create_context2; r600_init_screen_texture_functions(&rscreen->screen); r600_init_screen_resource_functions(&rscreen->screen); - rscreen->screen.user_buffer_create = r600_user_buffer_create2; +// rscreen->screen.user_buffer_create = r600_user_buffer_create2; return &rscreen->screen; } + +int r600_upload_index_buffer2(struct r600_pipe_context *rctx, struct r600_drawl *draw) +{ + struct pipe_resource *upload_buffer = NULL; + unsigned index_offset = draw->index_buffer_offset; + int ret = 0; + + if (r600_buffer_is_user_buffer(draw->index_buffer)) { + ret = u_upload_buffer(rctx->upload_ib, + index_offset, + draw->count * draw->index_size, + draw->index_buffer, + &index_offset, + &upload_buffer); + if (ret) { + goto done; + } + draw->index_buffer_offset = index_offset; + draw->index_buffer = upload_buffer; + } + +done: + return ret; +} + +int r600_upload_user_buffers2(struct r600_pipe_context *rctx) +{ + enum pipe_error ret = PIPE_OK; + int i, nr; + + nr = rctx->vertex_elements->count; + + for (i = 0; i < nr; i++) { + struct pipe_vertex_buffer *vb = + &rctx->vertex_buffer[rctx->vertex_elements->elements[i].vertex_buffer_index]; + + if (r600_buffer_is_user_buffer(vb->buffer)) { + struct pipe_resource *upload_buffer = NULL; + unsigned offset = 0; /*vb->buffer_offset * 4;*/ + unsigned size = vb->buffer->width0; + unsigned upload_offset; + ret = u_upload_buffer(rctx->upload_vb, + offset, size, + vb->buffer, + &upload_offset, &upload_buffer); + if (ret) + return ret; + + pipe_resource_reference(&vb->buffer, NULL); + vb->buffer = upload_buffer; + vb->buffer_offset = upload_offset; + } + } + return ret; +} |