diff options
author | Stéphane Marchesin <[email protected]> | 2011-06-06 20:42:30 -0700 |
---|---|---|
committer | Stéphane Marchesin <[email protected]> | 2011-06-06 20:42:30 -0700 |
commit | 7d2cb9a53c288ddafdf9cfd1b3162bcbb903de96 (patch) | |
tree | e73db7e19964211360dfe1096e029920c8cf98a6 /src | |
parent | abb436526974bd090853c0927ece0839f9143393 (diff) | |
parent | 22c320aa2c459474a0d220a40b849bf7e4864251 (diff) |
Merge branch 'master' of ssh://git.freedesktop.org/git/mesa/mesa
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 106 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600.h | 24 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 20 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 94 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 16 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/evergreen_hw_context.c | 142 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_hw_context.c | 397 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_priv.h | 4 |
8 files changed, 430 insertions, 373 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 54f5410c324..17abdff49cd 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -380,9 +380,8 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte struct pipe_resource *texture, const struct pipe_sampler_view *state) { - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_sampler_view *resource = CALLOC_STRUCT(r600_pipe_sampler_view); - struct r600_pipe_state *rstate; + struct r600_pipe_resource_state *rstate; const struct util_format_description *desc; struct r600_resource_texture *tmp; struct r600_resource *rbuffer; @@ -438,35 +437,27 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte array_mode = tmp->array_mode[0]; tile_type = tmp->tile_type; - r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, - S_030000_DIM(r600_tex_dim(texture->target)) | - S_030000_PITCH((pitch / 8) - 1) | - S_030000_NON_DISP_TILING_ORDER(tile_type) | - S_030000_TEX_WIDTH(texture->width0 - 1), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, - S_030004_TEX_HEIGHT(texture->height0 - 1) | - S_030004_TEX_DEPTH(texture->depth0 - 1) | - S_030004_ARRAY_MODE(array_mode), - 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2, - (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]); - r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3, - (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8, 0xFFFFFFFF, bo[1]); - r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4, - word4 | - S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) | - S_030010_ENDIAN_SWAP(endian) | - S_030010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5, - S_030014_LAST_LEVEL(state->u.tex.last_level) | - S_030014_BASE_ARRAY(0) | - S_030014_LAST_ARRAY(0), 0xffffffff, NULL); - r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, - S_030018_MAX_ANISO(4 /* max 16 samples */), - 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, - S_03001C_DATA_FORMAT(format) | - S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE), 0xFFFFFFFF, NULL); + rstate->bo[0] = bo[0]; + rstate->bo[1] = bo[1]; + rstate->val[0] = (S_030000_DIM(r600_tex_dim(texture->target)) | + S_030000_PITCH((pitch / 8) - 1) | + S_030000_NON_DISP_TILING_ORDER(tile_type) | + S_030000_TEX_WIDTH(texture->width0 - 1)); + rstate->val[1] = (S_030004_TEX_HEIGHT(texture->height0 - 1) | + S_030004_TEX_DEPTH(texture->depth0 - 1) | + S_030004_ARRAY_MODE(array_mode)); + rstate->val[2] = (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8; + rstate->val[3] = (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8; + rstate->val[4] = (word4 | + S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) | + S_030010_ENDIAN_SWAP(endian) | + S_030010_BASE_LEVEL(state->u.tex.first_level)); + rstate->val[5] = (S_030014_LAST_LEVEL(state->u.tex.last_level) | + S_030014_BASE_ARRAY(0) | + S_030014_LAST_ARRAY(0)); + rstate->val[6] = (S_030018_MAX_ANISO(4 /* max 16 samples */)); + rstate->val[7] = (S_03001C_DATA_FORMAT(format) | + S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE)); return &resource->base; } @@ -1769,45 +1760,32 @@ void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx) } void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, - struct r600_resource *rbuffer, - unsigned offset, unsigned stride) + struct r600_pipe_resource_state *rstate) { rstate->id = R600_PIPE_STATE_RESOURCE; - rstate->nregs = 0; - r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, - offset, 0xFFFFFFFF, rbuffer->bo); - r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, - rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2, - S_030008_ENDIAN_SWAP(r600_endian_swap(32)) | - S_030008_STRIDE(stride), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3, - S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) | - S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) | - S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) | - S_03000C_DST_SEL_W(V_03000C_SQ_SEL_W), - 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, - 0xC0000000, 0xFFFFFFFF, NULL); + + rstate->val[0] = 0; + rstate->bo[0] = NULL; + rstate->val[1] = 0; + rstate->val[2] = S_030008_ENDIAN_SWAP(r600_endian_swap(32)); + rstate->val[3] = S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) | + S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) | + S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) | + S_03000C_DST_SEL_W(V_03000C_SQ_SEL_W); + rstate->val[4] = 0; + rstate->val[5] = 0; + rstate->val[6] = 0; + rstate->val[7] = 0xc0000000; } -void evergreen_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, +void evergreen_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride) { - rstate->nregs = 0; - r600_pipe_state_mod_reg_bo(rstate, offset, rbuffer->bo); - r600_pipe_state_mod_reg(rstate, rbuffer->bo_size - offset - 1); - r600_pipe_state_mod_reg(rstate, S_030008_ENDIAN_SWAP(r600_endian_swap(32)) | - S_030008_STRIDE(stride)); - rstate->nregs = 8; - + rstate->bo[0] = rbuffer->bo; + rstate->val[0] = offset; + rstate->val[1] = rbuffer->bo_size - offset - 1; + rstate->val[2] = S_030008_ENDIAN_SWAP(r600_endian_swap(32)) | + S_030008_STRIDE(stride); } diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 23e7181a86e..b1444bf94f4 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -170,6 +170,12 @@ struct r600_pipe_state { struct r600_pipe_reg regs[R600_BLOCK_MAX_REG]; }; +struct r600_pipe_resource_state { + unsigned id; + u32 val[8]; + struct r600_bo *bo[2]; +}; + #define R600_BLOCK_STATUS_ENABLED (1 << 0) #define R600_BLOCK_STATUS_DIRTY (1 << 1) @@ -182,6 +188,7 @@ struct r600_block_reloc { struct r600_block { struct list_head list; + struct list_head enable_list; unsigned status; unsigned flags; unsigned start_offset; @@ -245,6 +252,7 @@ struct r600_context { unsigned nblocks; struct r600_block **blocks; struct list_head dirty; + struct list_head enable_list; unsigned pm4_ndwords; unsigned pm4_cdwords; unsigned pm4_dirty_cdwords; @@ -261,6 +269,10 @@ struct r600_context { unsigned num_dest_buffers; unsigned flags; boolean predicate_drawing; + struct r600_range ps_resources; + struct r600_range vs_resources; + struct r600_range fs_resources; + int num_ps_resources, num_vs_resources, num_fs_resources; }; struct r600_draw { @@ -275,9 +287,9 @@ struct r600_draw { int r600_context_init(struct r600_context *ctx, struct radeon *radeon); void r600_context_fini(struct r600_context *ctx); void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_state *state); -void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); void r600_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void r600_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void r600_context_flush(struct r600_context *ctx); @@ -303,9 +315,9 @@ void r600_context_flush_dest_caches(struct r600_context *ctx); int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon); void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *draw); void evergreen_context_flush_dest_caches(struct r600_context *ctx); -void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); void evergreen_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void evergreen_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 8002d943abd..f40d6fd3fa2 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -82,7 +82,7 @@ struct r600_screen { struct r600_pipe_sampler_view { struct pipe_sampler_view base; - struct r600_pipe_state state; + struct r600_pipe_resource_state state; }; struct r600_pipe_rasterizer { @@ -173,7 +173,7 @@ struct r600_pipe_context { struct r600_pipe_state *states[R600_PIPE_NSTATES]; struct r600_context ctx; struct r600_vertex_element *vertex_elements; - struct r600_pipe_state fs_resource[PIPE_MAX_ATTRIBS]; + struct r600_pipe_resource_state fs_resource[PIPE_MAX_ATTRIBS]; struct pipe_framebuffer_state framebuffer; struct pipe_index_buffer index_buffer; unsigned cb_target_mask; @@ -185,9 +185,9 @@ struct r600_pipe_context { struct r600_pipe_shader *ps_shader; struct r600_pipe_shader *vs_shader; struct r600_pipe_state vs_const_buffer; - struct r600_pipe_state vs_const_buffer_resource[R600_MAX_CONST_BUFFERS]; + struct r600_pipe_resource_state vs_const_buffer_resource[R600_MAX_CONST_BUFFERS]; struct r600_pipe_state ps_const_buffer; - struct r600_pipe_state ps_const_buffer_resource[R600_MAX_CONST_BUFFERS]; + struct r600_pipe_resource_state ps_const_buffer_resource[R600_MAX_CONST_BUFFERS]; struct r600_pipe_rasterizer *rasterizer; struct r600_pipe_state vgt; struct r600_pipe_state spi; @@ -224,10 +224,8 @@ void evergreen_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx); void evergreen_polygon_offset_update(struct r600_pipe_context *rctx); void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, - struct r600_resource *rbuffer, - unsigned offset, unsigned stride); -void evergreen_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, + struct r600_pipe_resource_state *rstate); +void evergreen_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride); @@ -268,10 +266,8 @@ void r600_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve) void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx); void r600_polygon_offset_update(struct r600_pipe_context *rctx); void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, - struct r600_resource *rbuffer, - unsigned offset, unsigned stride); -void r600_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, + struct r600_pipe_resource_state *rstate); +void r600_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index e9011de9fe0..4e62857343e 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -409,7 +409,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_sampler_view *resource = CALLOC_STRUCT(r600_pipe_sampler_view); - struct r600_pipe_state *rstate; + struct r600_pipe_resource_state *rstate; const struct util_format_description *desc; struct r600_resource_texture *tmp; struct r600_resource *rbuffer; @@ -472,33 +472,29 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c depth = texture->array_size; } - r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0, - S_038000_DIM(r600_tex_dim(texture->target)) | - S_038000_TILE_MODE(array_mode) | - S_038000_TILE_TYPE(tile_type) | - S_038000_PITCH((pitch / 8) - 1) | - S_038000_TEX_WIDTH(texture->width0 - 1), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1, - S_038004_TEX_HEIGHT(height - 1) | - S_038004_TEX_DEPTH(depth - 1) | - S_038004_DATA_FORMAT(format), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2, - (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]); - r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3, - (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8, 0xFFFFFFFF, bo[1]); - r600_pipe_state_add_reg(rstate, R_038010_RESOURCE0_WORD4, - word4 | - S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) | - S_038010_REQUEST_SIZE(1) | - S_038010_ENDIAN_SWAP(endian) | - S_038010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5, - S_038014_LAST_LEVEL(state->u.tex.last_level) | - S_038014_BASE_ARRAY(state->u.tex.first_layer) | - S_038014_LAST_ARRAY(state->u.tex.last_layer), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6, - S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) | - S_038018_MAX_ANISO(4 /* max 16 samples */), 0xFFFFFFFF, NULL); + rstate->bo[0] = bo[0]; + rstate->bo[1] = bo[1]; + + rstate->val[0] = (S_038000_DIM(r600_tex_dim(texture->target)) | + S_038000_TILE_MODE(array_mode) | + S_038000_TILE_TYPE(tile_type) | + S_038000_PITCH((pitch / 8) - 1) | + S_038000_TEX_WIDTH(texture->width0 - 1)); + rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) | + S_038004_TEX_DEPTH(depth - 1) | + S_038004_DATA_FORMAT(format)); + rstate->val[2] = (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8; + rstate->val[3] = (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8; + rstate->val[4] = (word4 | + S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) | + S_038010_REQUEST_SIZE(1) | + S_038010_ENDIAN_SWAP(endian) | + S_038010_BASE_LEVEL(state->u.tex.first_level)); + rstate->val[5] = (S_038014_LAST_LEVEL(state->u.tex.last_level) | + S_038014_BASE_ARRAY(state->u.tex.first_layer) | + S_038014_LAST_ARRAY(state->u.tex.last_layer)); + rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) | + S_038018_MAX_ANISO(4 /* max 16 samples */)); return &resource->base; } @@ -1481,37 +1477,27 @@ void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx) } void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, - struct r600_resource *rbuffer, - unsigned offset, unsigned stride) + struct r600_pipe_resource_state *rstate) { rstate->id = R600_PIPE_STATE_RESOURCE; - rstate->nregs = 0; - r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0, - offset, 0xFFFFFFFF, rbuffer->bo); - r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1, - rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2, - S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | - S_038008_STRIDE(stride), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038010_RESOURCE0_WORD4, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6, - 0xC0000000, 0xFFFFFFFF, NULL); + + rstate->bo[0] = NULL; + rstate->val[0] = 0; + rstate->val[1] = 0; + rstate->val[2] = 0; + rstate->val[3] = 0; + rstate->val[4] = 0; + rstate->val[5] = 0; + rstate->val[6] = 0xc0000000; } -void r600_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, +void r600_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride) { - rstate->nregs = 0; - r600_pipe_state_mod_reg_bo(rstate, offset, rbuffer->bo); - r600_pipe_state_mod_reg(rstate, rbuffer->bo_size - offset - 1); - r600_pipe_state_mod_reg(rstate, S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | - S_038008_STRIDE(stride)); - rstate->nregs = 7; + rstate->val[0] = offset; + rstate->bo[0] = rbuffer->bo; + rstate->val[1] = rbuffer->bo_size - offset - 1; + rstate->val[2] = S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | + S_038008_STRIDE(stride); } diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 48ab15f9323..0928d964dc2 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -388,7 +388,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource_buffer *rbuffer = r600_buffer(buffer); - struct r600_pipe_state *rstate; + struct r600_pipe_resource_state *rstate; uint32_t offset; /* Note that the state tracker can unbind constant buffers by @@ -416,9 +416,9 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, rstate = &rctx->vs_const_buffer_resource[index]; if (!rstate->id) { if (rctx->family >= CHIP_CEDAR) { - evergreen_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + evergreen_pipe_init_buffer_resource(rctx, rstate); } else { - r600_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + r600_pipe_init_buffer_resource(rctx, rstate); } } @@ -444,9 +444,9 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, rstate = &rctx->ps_const_buffer_resource[index]; if (!rstate->id) { if (rctx->family >= CHIP_CEDAR) { - evergreen_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + evergreen_pipe_init_buffer_resource(rctx, rstate); } else { - r600_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + r600_pipe_init_buffer_resource(rctx, rstate); } } if (rctx->family >= CHIP_CEDAR) { @@ -468,7 +468,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) { - struct r600_pipe_state *rstate; + struct r600_pipe_resource_state *rstate; struct r600_resource *rbuffer; struct pipe_vertex_buffer *vertex_buffer; unsigned i, count, offset; @@ -503,9 +503,9 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) if (!rstate->id) { if (rctx->family >= CHIP_CEDAR) { - evergreen_pipe_init_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); + evergreen_pipe_init_buffer_resource(rctx, rstate); } else { - r600_pipe_init_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); + r600_pipe_init_buffer_resource(rctx, rstate); } } diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c index cf8ae5185b4..3cf41c1f9f9 100644 --- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c +++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c @@ -43,31 +43,31 @@ static const struct r600_reg evergreen_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0, 0}, {R_008A14_PA_CL_ENHANCE, 0, 0, 0}, - {R_008C00_SQ_CONFIG, 0, 0, 0}, - {R_008C04_SQ_GPR_RESOURCE_MGMT_1, 0, 0, 0}, - {R_008C08_SQ_GPR_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008C0C_SQ_THREAD_RESOURCE_MGMT, 0, 0, 0}, - {R_008C18_SQ_THREAD_RESOURCE_MGMT_1, 0, 0, 0}, - {R_008C1C_SQ_THREAD_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008C20_SQ_STACK_RESOURCE_MGMT_1, 0, 0, 0}, - {R_008C24_SQ_STACK_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008C28_SQ_STACK_RESOURCE_MGMT_3, 0, 0, 0}, - {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0, 0, 0}, - {R_009100_SPI_CONFIG_CNTL, 0, 0, 0}, - {R_00913C_SPI_CONFIG_CNTL_1, 0, 0, 0}, + {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C08_SQ_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C0C_SQ_THREAD_RESOURCE_MGMT, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C18_SQ_THREAD_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C1C_SQ_THREAD_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C20_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C24_SQ_STACK_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C28_SQ_STACK_RESOURCE_MGMT_3, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, }; static const struct r600_reg cayman_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0, 0}, {R_008A14_PA_CL_ENHANCE, 0, 0, 0}, - {R_008C00_SQ_CONFIG, 0, 0, 0}, - {R_008C04_SQ_GPR_RESOURCE_MGMT_1, 0, 0, 0}, - {CM_R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, 0, 0, 0}, - {CM_R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0, 0, 0}, - {R_009100_SPI_CONFIG_CNTL, 0, 0, 0}, - {R_00913C_SPI_CONFIG_CNTL_1, 0, 0, 0}, + {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {CM_R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {CM_R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, }; static const struct r600_reg evergreen_ctl_const_list[] = { @@ -817,7 +817,7 @@ static const struct r600_reg cayman_context_reg_list[] = { }; /* SHADER RESOURCE R600/R700 */ -static int evergreen_state_resource_init(struct r600_context *ctx, u32 offset) +static int r600_resource_range_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride) { struct r600_reg r600_shader_resource[] = { {R_030000_RESOURCE0_WORD0, 0, 0, 0}, @@ -831,10 +831,7 @@ static int evergreen_state_resource_init(struct r600_context *ctx, u32 offset) }; unsigned nreg = Elements(r600_shader_resource); - for (int i = 0; i < nreg; i++) { - r600_shader_resource[i].offset += offset; - } - return r600_context_add_block(ctx, r600_shader_resource, nreg, PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET); + return r600_resource_init(ctx, range, offset, nblocks, stride, r600_shader_resource, nreg, EVERGREEN_RESOURCE_OFFSET); } /* SHADER SAMPLER R600/R700 */ @@ -907,6 +904,10 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon) ctx->radeon = radeon; LIST_INITHEAD(&ctx->query_list); + /* init dirty list */ + LIST_INITHEAD(&ctx->dirty); + LIST_INITHEAD(&ctx->enable_list); + ctx->range = calloc(NUM_RANGES, sizeof(struct r600_range)); if (!ctx->range) { r = -ENOMEM; @@ -960,24 +961,19 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon) if (r) goto out_err; } - /* PS RESOURCE */ - for (int j = 0, offset = 0; j < 176; j++, offset += 0x20) { - r = evergreen_state_resource_init(ctx, offset); - if (r) - goto out_err; - } - /* VS RESOURCE */ - for (int j = 0, offset = 0x1600; j < 160; j++, offset += 0x20) { - r = evergreen_state_resource_init(ctx, offset); - if (r) - goto out_err; - } - /* FS RESOURCE */ - for (int j = 0, offset = 0x7C00; j < 16; j++, offset += 0x20) { - r = evergreen_state_resource_init(ctx, offset); - if (r) - goto out_err; - } + + ctx->num_ps_resources = 176; + ctx->num_vs_resources = 160; + ctx->num_fs_resources = 16; + r = r600_resource_range_init(ctx, &ctx->ps_resources, 0, 176, 0x20); + if (r) + goto out_err; + r = r600_resource_range_init(ctx, &ctx->vs_resources, 0x1600, 160, 0x20); + if (r) + goto out_err; + r = r600_resource_range_init(ctx, &ctx->fs_resources, 0x7C00, 16, 0x20); + if (r) + goto out_err; /* PS loop const */ evergreen_loop_const_init(ctx, 0); @@ -1015,33 +1011,31 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon) LIST_INITHEAD(&ctx->fenced_bo); - /* init dirty list */ - LIST_INITHEAD(&ctx->dirty); return 0; out_err: r600_context_fini(ctx); return r; } -void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid) +void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid) { - unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x20 * rid; + struct r600_block *block = ctx->ps_resources.blocks[rid]; - r600_context_pipe_state_set_resource(ctx, state, offset); + r600_context_pipe_state_set_resource(ctx, state, block); } -void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid) +void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid) { - unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x1600 + 0x20 * rid; + struct r600_block *block = ctx->vs_resources.blocks[rid]; - r600_context_pipe_state_set_resource(ctx, state, offset); + r600_context_pipe_state_set_resource(ctx, state, block); } -void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid) +void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid) { - unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x7C00 + 0x20 * rid; + struct r600_block *block = ctx->fs_resources.blocks[rid]; - r600_context_pipe_state_set_resource(ctx, state, offset); + r600_context_pipe_state_set_resource(ctx, state, block); } static inline void evergreen_context_pipe_state_set_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset) @@ -1056,6 +1050,7 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } dirty = block->status & R600_BLOCK_STATUS_DIRTY; @@ -1066,8 +1061,8 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context block->reg[i] = state->regs[i].value; } } - - r600_context_dirty_block(ctx, block, dirty, 2); + if (dirty) + r600_context_dirty_block(ctx, block, dirty, 2); } static inline void evergreen_context_ps_partial_flush(struct r600_context *ctx) @@ -1094,6 +1089,7 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } if (state->nregs <= 3) { @@ -1119,7 +1115,8 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c if (dirty & R600_BLOCK_STATUS_DIRTY) evergreen_context_ps_partial_flush(ctx); - r600_context_dirty_block(ctx, block, dirty, 4); + if (dirty) + r600_context_dirty_block(ctx, block, dirty, 4); } void evergreen_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id) @@ -1146,6 +1143,7 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr unsigned ndwords = 7; struct r600_block *dirty_block = NULL; struct r600_block *next_block; + uint32_t *pm4; if (draw->indices) { ndwords = 11; @@ -1187,24 +1185,26 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr } /* draw packet */ - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type; - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_instances; + pm4 = &ctx->pm4[ctx->pm4_cdwords]; + pm4[0] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing); + pm4[1] = draw->vgt_index_type; + pm4[2] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing); + pm4[3] = draw->vgt_num_instances; if (draw->indices) { - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->indices_bo_offset + r600_bo_offset(draw->indices); - ctx->pm4[ctx->pm4_cdwords++] = 0; - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices; - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator; - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = 0; - r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], draw->indices); + pm4[4] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing); + pm4[5] = draw->indices_bo_offset + r600_bo_offset(draw->indices); + pm4[6] = 0; + pm4[7] = draw->vgt_num_indices; + pm4[8] = draw->vgt_draw_initiator; + pm4[9] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); + pm4[10] = 0; + r600_context_bo_reloc(ctx, &pm4[10], draw->indices); } else { - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices; - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator; + pm4[4] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, ctx->predicate_drawing); + pm4[5] = draw->vgt_num_indices; + pm4[6] = draw->vgt_draw_initiator; } + ctx->pm4_cdwords += ndwords; ctx->flags |= (R600_CONTEXT_DRAW_PENDING | R600_CONTEXT_DST_CACHES_DIRTY); diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index a3c8945a722..cb244f2b9ee 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -79,6 +79,66 @@ static void INLINE r600_context_fence_wraparound(struct r600_context *ctx, unsig } } +static void r600_init_block(struct r600_context *ctx, + struct r600_block *block, + const struct r600_reg *reg, int index, int nreg, + unsigned opcode, unsigned offset_base) +{ + int i = index; + int j, n = nreg; + + /* initialize block */ + block->status |= R600_BLOCK_STATUS_DIRTY; /* dirty all blocks at start */ + block->start_offset = reg[i].offset; + block->pm4[block->pm4_ndwords++] = PKT3(opcode, n, 0); + block->pm4[block->pm4_ndwords++] = (block->start_offset - offset_base) >> 2; + block->reg = &block->pm4[block->pm4_ndwords]; + block->pm4_ndwords += n; + block->nreg = n; + block->nreg_dirty = n; + block->flags = 0; + LIST_INITHEAD(&block->list); + LIST_INITHEAD(&block->enable_list); + + for (j = 0; j < n; j++) { + if (reg[i+j].flags & REG_FLAG_DIRTY_ALWAYS) { + block->flags |= REG_FLAG_DIRTY_ALWAYS; + } + if (reg[i+j].flags & REG_FLAG_ENABLE_ALWAYS) { + block->status |= R600_BLOCK_STATUS_ENABLED; + LIST_ADDTAIL(&block->enable_list, &ctx->enable_list); + } + + if (reg[i+j].flags & REG_FLAG_NEED_BO) { + block->nbo++; + assert(block->nbo < R600_BLOCK_MAX_BO); + block->pm4_bo_index[j] = block->nbo; + block->pm4[block->pm4_ndwords++] = PKT3(PKT3_NOP, 0, 0); + block->pm4[block->pm4_ndwords++] = 0x00000000; + if (reg[i+j].flags & REG_FLAG_RV6XX_SBU) { + block->reloc[block->nbo].flush_flags = 0; + block->reloc[block->nbo].flush_mask = 0; + } else { + block->reloc[block->nbo].flush_flags = reg[i+j].flush_flags; + block->reloc[block->nbo].flush_mask = reg[i+j].flush_mask; + } + block->reloc[block->nbo].bo_pm4_index = block->pm4_ndwords - 1; + } + if ((ctx->radeon->family > CHIP_R600) && + (ctx->radeon->family < CHIP_RV770) && reg[i+j].flags & REG_FLAG_RV6XX_SBU) { + block->pm4[block->pm4_ndwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); + block->pm4[block->pm4_ndwords++] = reg[i+j].flush_flags; + } + } + for (j = 0; j < n; j++) { + if (reg[i+j].flush_flags) { + block->pm4_flush_ndwords += 7; + } + } + /* check that we stay in limit */ + assert(block->pm4_ndwords < R600_BLOCK_MAX_REG); +} + int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, unsigned nreg, unsigned opcode, unsigned offset_base) { @@ -87,8 +147,6 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, int offset; for (unsigned i = 0, n = 0; i < nreg; i += n) { - u32 j; - /* ignore new block balise */ if (reg[i].offset == GROUP_FORCE_NEW_BLOCK) { n = 1; @@ -131,50 +189,8 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, range->blocks[CTX_BLOCK_ID(reg[i + j].offset)] = block; } - /* initialize block */ - block->status |= R600_BLOCK_STATUS_DIRTY; /* dirty all blocks at start */ - block->start_offset = reg[i].offset; - block->pm4[block->pm4_ndwords++] = PKT3(opcode, n, 0); - block->pm4[block->pm4_ndwords++] = (block->start_offset - offset_base) >> 2; - block->reg = &block->pm4[block->pm4_ndwords]; - block->pm4_ndwords += n; - block->nreg = n; - block->nreg_dirty = n; - block->flags = 0; - LIST_INITHEAD(&block->list); - - for (j = 0; j < n; j++) { - if (reg[i+j].flags & REG_FLAG_DIRTY_ALWAYS) { - block->flags |= REG_FLAG_DIRTY_ALWAYS; - } - if (reg[i+j].flags & REG_FLAG_NEED_BO) { - block->nbo++; - assert(block->nbo < R600_BLOCK_MAX_BO); - block->pm4_bo_index[j] = block->nbo; - block->pm4[block->pm4_ndwords++] = PKT3(PKT3_NOP, 0, 0); - block->pm4[block->pm4_ndwords++] = 0x00000000; - if (reg[i+j].flags & REG_FLAG_RV6XX_SBU) { - block->reloc[block->nbo].flush_flags = 0; - block->reloc[block->nbo].flush_mask = 0; - } else { - block->reloc[block->nbo].flush_flags = reg[i+j].flush_flags; - block->reloc[block->nbo].flush_mask = reg[i+j].flush_mask; - } - block->reloc[block->nbo].bo_pm4_index = block->pm4_ndwords - 1; - } - if ((ctx->radeon->family > CHIP_R600) && - (ctx->radeon->family < CHIP_RV770) && reg[i+j].flags & REG_FLAG_RV6XX_SBU) { - block->pm4[block->pm4_ndwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); - block->pm4[block->pm4_ndwords++] = reg[i+j].flush_flags; - } - } - for (j = 0; j < n; j++) { - if (reg[i+j].flush_flags) { - block->pm4_flush_ndwords += 7; - } - } - /* check that we stay in limit */ - assert(block->pm4_ndwords < R600_BLOCK_MAX_REG); + r600_init_block(ctx, block, reg, i, n, opcode, offset_base); + } return 0; } @@ -552,7 +568,31 @@ static const struct r600_reg r600_context_reg_list[] = { }; /* SHADER RESOURCE R600/R700 */ -static int r600_state_resource_init(struct r600_context *ctx, u32 offset) +int r600_resource_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride, struct r600_reg *reg, int nreg, unsigned offset_base) +{ + int i; + struct r600_block *block; + range->blocks = calloc(nblocks, sizeof(struct r600_block *)); + if (range->blocks == NULL) + return -ENOMEM; + + reg[0].offset += offset; + for (i = 0; i < nblocks; i++) { + block = calloc(1, sizeof(struct r600_block)); + if (block == NULL) { + return -ENOMEM; + } + ctx->nblocks++; + range->blocks[i] = block; + r600_init_block(ctx, block, reg, 0, nreg, PKT3_SET_RESOURCE, offset_base); + + reg[0].offset += stride; + } + return 0; +} + + +static int r600_resource_range_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride) { struct r600_reg r600_shader_resource[] = { {R_038000_RESOURCE0_WORD0, 0, 0, 0}, @@ -565,10 +605,7 @@ static int r600_state_resource_init(struct r600_context *ctx, u32 offset) }; unsigned nreg = Elements(r600_shader_resource); - for (int i = 0; i < nreg; i++) { - r600_shader_resource[i].offset += offset; - } - return r600_context_add_block(ctx, r600_shader_resource, nreg, PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET); + return r600_resource_init(ctx, range, offset, nblocks, stride, r600_shader_resource, nreg, R600_RESOURCE_OFFSET); } /* SHADER SAMPLER R600/R700 */ @@ -630,6 +667,22 @@ static void r600_context_clear_fenced_bo(struct r600_context *ctx) } } +static void r600_free_resource_range(struct r600_context *ctx, struct r600_range *range, int nblocks) +{ + struct r600_block *block; + int i; + for (i = 0; i < nblocks; i++) { + block = range->blocks[i]; + if (block) { + for (int k = 1; k <= block->nbo; k++) + r600_bo_reference(ctx->radeon, &block->reloc[k].bo, NULL); + free(block); + } + } + free(range->blocks); + +} + /* initialize */ void r600_context_fini(struct r600_context *ctx) { @@ -654,6 +707,9 @@ void r600_context_fini(struct r600_context *ctx) } free(ctx->range[i].blocks); } + r600_free_resource_range(ctx, &ctx->ps_resources, ctx->num_ps_resources); + r600_free_resource_range(ctx, &ctx->vs_resources, ctx->num_vs_resources); + r600_free_resource_range(ctx, &ctx->fs_resources, ctx->num_fs_resources); free(ctx->range); free(ctx->blocks); free(ctx->reloc); @@ -664,13 +720,26 @@ void r600_context_fini(struct r600_context *ctx) memset(ctx, 0, sizeof(struct r600_context)); } +static void r600_add_resource_block(struct r600_context *ctx, struct r600_range *range, int num_blocks, int *index) +{ + int c = *index; + for (int j = 0; j < num_blocks; j++) { + if (!range->blocks[j]) + continue; + + ctx->blocks[c++] = range->blocks[j]; + } + *index = c; +} + int r600_setup_block_table(struct r600_context *ctx) { /* setup block table */ + int c = 0; ctx->blocks = calloc(ctx->nblocks, sizeof(void*)); if (!ctx->blocks) return -ENOMEM; - for (int i = 0, c = 0; i < NUM_RANGES; i++) { + for (int i = 0; i < NUM_RANGES; i++) { if (!ctx->range[i].blocks) continue; for (int j = 0, add; j < (1 << HASH_SHIFT); j++) { @@ -691,6 +760,10 @@ int r600_setup_block_table(struct r600_context *ctx) } } } + + r600_add_resource_block(ctx, &ctx->ps_resources, ctx->num_ps_resources, &c); + r600_add_resource_block(ctx, &ctx->vs_resources, ctx->num_vs_resources, &c); + r600_add_resource_block(ctx, &ctx->fs_resources, ctx->num_fs_resources, &c); return 0; } @@ -702,6 +775,10 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon) ctx->radeon = radeon; LIST_INITHEAD(&ctx->query_list); + /* init dirty list */ + LIST_INITHEAD(&ctx->dirty); + LIST_INITHEAD(&ctx->enable_list); + ctx->range = calloc(NUM_RANGES, sizeof(struct r600_range)); if (!ctx->range) { r = -ENOMEM; @@ -747,24 +824,19 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon) if (r) goto out_err; } - /* PS RESOURCE */ - for (int j = 0, offset = 0; j < 160; j++, offset += 0x1C) { - r = r600_state_resource_init(ctx, offset); - if (r) - goto out_err; - } - /* VS RESOURCE */ - for (int j = 0, offset = 0x1180; j < 160; j++, offset += 0x1C) { - r = r600_state_resource_init(ctx, offset); - if (r) - goto out_err; - } - /* FS RESOURCE */ - for (int j = 0, offset = 0x2300; j < 16; j++, offset += 0x1C) { - r = r600_state_resource_init(ctx, offset); - if (r) - goto out_err; - } + + ctx->num_ps_resources = 160; + ctx->num_vs_resources = 160; + ctx->num_fs_resources = 16; + r = r600_resource_range_init(ctx, &ctx->ps_resources, 0, 160, 0x1c); + if (r) + goto out_err; + r = r600_resource_range_init(ctx, &ctx->vs_resources, 0x1180, 160, 0x1c); + if (r) + goto out_err; + r = r600_resource_range_init(ctx, &ctx->fs_resources, 0x2300, 16, 0x1c); + if (r) + goto out_err; /* PS loop const */ r600_loop_const_init(ctx, 0); @@ -800,9 +872,6 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon) LIST_INITHEAD(&ctx->fenced_bo); - /* init dirty list */ - LIST_INITHEAD(&ctx->dirty); - ctx->max_db = 4; return 0; @@ -920,20 +989,24 @@ void r600_context_reg(struct r600_context *ctx, dirty |= R600_BLOCK_STATUS_DIRTY; block->reg[id] = new_val; } - r600_context_dirty_block(ctx, block, dirty, id); + if (dirty) + r600_context_dirty_block(ctx, block, dirty, id); } -void r600_context_dirty_block(struct r600_context *ctx, struct r600_block *block, +void r600_context_dirty_block(struct r600_context *ctx, + struct r600_block *block, int dirty, int index) { - if (dirty && (index + 1) > block->nreg_dirty) + if ((index + 1) > block->nreg_dirty) block->nreg_dirty = index + 1; if ((dirty != (block->status & R600_BLOCK_STATUS_DIRTY)) || !(block->status & R600_BLOCK_STATUS_ENABLED)) { - - block->status |= R600_BLOCK_STATUS_ENABLED; block->status |= R600_BLOCK_STATUS_DIRTY; ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords; + if (!(block->status & R600_BLOCK_STATUS_ENABLED)) { + block->status |= R600_BLOCK_STATUS_ENABLED; + LIST_ADDTAIL(&block->enable_list, &ctx->enable_list); + } LIST_ADDTAIL(&block->list,&ctx->dirty); } } @@ -970,20 +1043,18 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat dirty |= R600_BLOCK_STATUS_DIRTY; } - r600_context_dirty_block(ctx, block, dirty, id); + if (dirty) + r600_context_dirty_block(ctx, block, dirty, id); } } -void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset) +void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, struct r600_block *block) { - struct r600_range *range; - struct r600_block *block; int i; int dirty; int num_regs = ctx->radeon->chip_class >= EVERGREEN ? 8 : 7; + boolean is_vertex; - range = &ctx->range[CTX_RANGE_ID(offset)]; - block = range->blocks[CTX_BLOCK_ID(offset)]; if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); if (block->reloc[1].bo) @@ -992,15 +1063,17 @@ void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_ r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL); r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } + is_vertex = ((state->val[num_regs-1] & 0xc0000000) == 0xc0000000); dirty = block->status & R600_BLOCK_STATUS_DIRTY; for (i = 0; i < num_regs; i++) { - if (block->reg[i] != state->regs[i].value) { + if (dirty || (block->reg[i] != state->val[i])) { dirty |= R600_BLOCK_STATUS_DIRTY; - block->reg[i] = state->regs[i].value; + block->reg[i] = state->val[i]; } } @@ -1009,64 +1082,65 @@ void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_ dirty |= R600_BLOCK_STATUS_DIRTY; if (!dirty) { - if (state->regs[0].bo) { - if ((block->reloc[1].bo->bo->handle != state->regs[0].bo->bo->handle) || - (block->reloc[2].bo->bo->handle != state->regs[0].bo->bo->handle)) + if (is_vertex) { + if ((block->reloc[1].bo->bo->handle != state->bo[0]->bo->handle) || + (block->reloc[2].bo->bo->handle != state->bo[0]->bo->handle)) dirty |= R600_BLOCK_STATUS_DIRTY; } else { - if ((block->reloc[1].bo->bo->handle != state->regs[2].bo->bo->handle) || - (block->reloc[2].bo->bo->handle != state->regs[3].bo->bo->handle)) + if ((block->reloc[1].bo->bo->handle != state->bo[0]->bo->handle) || + (block->reloc[2].bo->bo->handle != state->bo[1]->bo->handle)) dirty |= R600_BLOCK_STATUS_DIRTY; } } if (!dirty) { - if (state->regs[0].bo) - state->regs[0].bo->fence = ctx->radeon->fence; + if (is_vertex) + state->bo[0]->fence = ctx->radeon->fence; else { - state->regs[2].bo->fence = ctx->radeon->fence; - state->regs[3].bo->fence = ctx->radeon->fence; + state->bo[0]->fence = ctx->radeon->fence; + state->bo[1]->fence = ctx->radeon->fence; } } else { r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL); r600_bo_reference(ctx->radeon, &block->reloc[2].bo, NULL); - if (state->regs[0].bo) { + if (is_vertex) { /* VERTEX RESOURCE, we preted there is 2 bo to relocate so * we have single case btw VERTEX & TEXTURE resource */ - r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[0].bo); - r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[0].bo); - state->regs[0].bo->fence = ctx->radeon->fence; + r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->bo[0]); + r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->bo[0]); + state->bo[0]->fence = ctx->radeon->fence; } else { /* TEXTURE RESOURCE */ - r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[2].bo); - r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[3].bo); - state->regs[2].bo->fence = ctx->radeon->fence; - state->regs[3].bo->fence = ctx->radeon->fence; - state->regs[2].bo->bo->binding |= BO_BOUND_TEXTURE; + r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->bo[0]); + r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->bo[1]); + state->bo[0]->fence = ctx->radeon->fence; + state->bo[1]->fence = ctx->radeon->fence; + state->bo[0]->bo->binding |= BO_BOUND_TEXTURE; } } - r600_context_dirty_block(ctx, block, dirty, num_regs - 1); + if (dirty) + r600_context_dirty_block(ctx, block, dirty, num_regs - 1); } -void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid) +void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid) { - unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x1C * rid; + struct r600_block *block = ctx->ps_resources.blocks[rid]; - r600_context_pipe_state_set_resource(ctx, state, offset); + r600_context_pipe_state_set_resource(ctx, state, block); } -void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid) +void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid) { - unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x1180 + 0x1C * rid; + struct r600_block *block = ctx->vs_resources.blocks[rid]; - r600_context_pipe_state_set_resource(ctx, state, offset); + r600_context_pipe_state_set_resource(ctx, state, block); } -void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid) +void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid) { - unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x2300 + 0x1C * rid; + struct r600_block *block = ctx->fs_resources.blocks[rid]; - r600_context_pipe_state_set_resource(ctx, state, offset); + r600_context_pipe_state_set_resource(ctx, state, block); } static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset) @@ -1081,6 +1155,7 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } dirty = block->status & R600_BLOCK_STATUS_DIRTY; @@ -1091,7 +1166,8 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, } } - r600_context_dirty_block(ctx, block, dirty, 2); + if (dirty) + r600_context_dirty_block(ctx, block, dirty, 2); } static inline void r600_context_ps_partial_flush(struct r600_context *ctx) @@ -1117,6 +1193,7 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } if (state->nregs <= 3) { @@ -1135,8 +1212,8 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex * will end up using the new border color. */ if (dirty & R600_BLOCK_STATUS_DIRTY) r600_context_ps_partial_flush(ctx); - - r600_context_dirty_block(ctx, block, dirty, 3); + if (dirty) + r600_context_dirty_block(ctx, block, dirty, 3); } void r600_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id) @@ -1179,31 +1256,33 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block * { int id; int optional = block->nbo == 0 && !(block->flags & REG_FLAG_DIRTY_ALWAYS); - int cp_dwords = block->pm4_ndwords, start_dword; - int new_dwords; + int cp_dwords = block->pm4_ndwords, start_dword = 0; + int new_dwords = 0; if (block->nreg_dirty == 0 && optional) { goto out; } - optional &= (block->nreg_dirty != block->nreg); - - ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH; - for (int j = 0; j < block->nreg; j++) { - if (block->pm4_bo_index[j]) { - /* find relocation */ - id = block->pm4_bo_index[j]; - r600_context_bo_reloc(ctx, - &block->pm4[block->reloc[id].bo_pm4_index], - block->reloc[id].bo); - r600_context_bo_flush(ctx, - block->reloc[id].flush_flags, - block->reloc[id].flush_mask, - block->reloc[id].bo); + if (block->nbo) { + ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH; + + for (int j = 0; j < block->nreg; j++) { + if (block->pm4_bo_index[j]) { + /* find relocation */ + id = block->pm4_bo_index[j]; + r600_context_bo_reloc(ctx, + &block->pm4[block->reloc[id].bo_pm4_index], + block->reloc[id].bo); + r600_context_bo_flush(ctx, + block->reloc[id].flush_flags, + block->reloc[id].flush_mask, + block->reloc[id].bo); + } } + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; } - ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; + optional &= (block->nreg_dirty != block->nreg); if (optional) { new_dwords = block->nreg_dirty; start_dword = ctx->pm4_cdwords; @@ -1268,6 +1347,7 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) unsigned ndwords = 7; struct r600_block *dirty_block = NULL; struct r600_block *next_block; + uint32_t *pm4; if (draw->indices) { ndwords = 11; @@ -1310,24 +1390,27 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) } /* draw packet */ - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type; - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_instances; + pm4 = &ctx->pm4[ctx->pm4_cdwords]; + + pm4[0] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing); + pm4[1] = draw->vgt_index_type; + pm4[2] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing); + pm4[3] = draw->vgt_num_instances; if (draw->indices) { - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->indices_bo_offset + r600_bo_offset(draw->indices); - ctx->pm4[ctx->pm4_cdwords++] = 0; - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices; - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator; - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = 0; - r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], draw->indices); + pm4[4] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing); + pm4[5] = draw->indices_bo_offset + r600_bo_offset(draw->indices); + pm4[6] = 0; + pm4[7] = draw->vgt_num_indices; + pm4[8] = draw->vgt_draw_initiator; + pm4[9] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); + pm4[10] = 0; + r600_context_bo_reloc(ctx, &pm4[10], draw->indices); } else { - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices; - ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator; + pm4[4] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, ctx->predicate_drawing); + pm4[5] = draw->vgt_num_indices; + pm4[6] = draw->vgt_draw_initiator; } + ctx->pm4_cdwords += ndwords; ctx->flags |= (R600_CONTEXT_DST_CACHES_DIRTY | R600_CONTEXT_DRAW_PENDING); @@ -1342,6 +1425,7 @@ void r600_context_flush(struct r600_context *ctx) uint64_t chunk_array[2]; unsigned fence; int r; + struct r600_block *enable_block = NULL, *next_block; if (!ctx->pm4_cdwords) return; @@ -1415,15 +1499,14 @@ void r600_context_flush(struct r600_context *ctx) /* set all valid group as dirty so they get reemited on * next draw command */ - for (int i = 0; i < ctx->nblocks; i++) { - if (ctx->blocks[i]->status & R600_BLOCK_STATUS_ENABLED) { - if(!(ctx->blocks[i]->status & R600_BLOCK_STATUS_DIRTY)) { - LIST_ADDTAIL(&ctx->blocks[i]->list,&ctx->dirty); - } - ctx->pm4_dirty_cdwords += ctx->blocks[i]->pm4_ndwords + ctx->blocks[i]->pm4_flush_ndwords; - ctx->blocks[i]->status |= R600_BLOCK_STATUS_DIRTY; - ctx->blocks[i]->nreg_dirty = ctx->blocks[i]->nreg; + LIST_FOR_EACH_ENTRY(enable_block, &ctx->enable_list, enable_list) { + if(!(enable_block->status & R600_BLOCK_STATUS_DIRTY)) { + LIST_ADDTAIL(&enable_block->list,&ctx->dirty); } + ctx->pm4_dirty_cdwords += enable_block->pm4_ndwords + + enable_block->pm4_flush_ndwords; + enable_block->status |= R600_BLOCK_STATUS_DIRTY; + enable_block->nreg_dirty = enable_block->nreg; } } diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 9be5c358f85..d9cb52409cd 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -66,6 +66,7 @@ struct radeon { #define REG_FLAG_DIRTY_ALWAYS 2 #define REG_FLAG_RV6XX_SBU 4 #define REG_FLAG_NOT_R600 8 +#define REG_FLAG_ENABLE_ALWAYS 16 struct r600_reg { unsigned offset; @@ -158,7 +159,7 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, struct r600_bo *r600_context_reg_bo(struct r600_context *ctx, unsigned offset); int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, unsigned nreg, unsigned opcode, unsigned offset_base); -void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset); +void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, struct r600_block *block); void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *block); void r600_context_dirty_block(struct r600_context *ctx, struct r600_block *block, int dirty, int index); @@ -167,6 +168,7 @@ void r600_context_reg(struct r600_context *ctx, unsigned offset, unsigned value, unsigned mask); void r600_init_cs(struct r600_context *ctx); +int r600_resource_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride, struct r600_reg *reg, int nreg, unsigned offset_base); /* * r600_bo.c */ |