From 2df399c34bb39122a45bdd5b430b48346542e1cb Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 1 Aug 2012 15:53:11 -0400 Subject: [PATCH] r600g: atomize sampler state v2 Use atom for sampler state. Does not provide new functionality or fix any bug. Just a step toward full atom base r600g. v2: Split seamless on r6xx/r7xx into it's own atom. Make sure it's emited after sampler and with a pipeline flush before otherwise it does not take effect. Signed-off-by: Jerome Glisse --- .../drivers/r600/evergreen_hw_context.c | 117 ---------- src/gallium/drivers/r600/evergreen_state.c | 136 ++++++----- src/gallium/drivers/r600/r600.h | 5 +- src/gallium/drivers/r600/r600_hw_context.c | 149 +----------- src/gallium/drivers/r600/r600_pipe.h | 24 +- src/gallium/drivers/r600/r600_state.c | 217 +++++++++--------- src/gallium/drivers/r600/r600_state_common.c | 66 +++++- 7 files changed, 262 insertions(+), 452 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c index 199033f7ae3..6494786b048 100644 --- a/src/gallium/drivers/r600/evergreen_hw_context.c +++ b/src/gallium/drivers/r600/evergreen_hw_context.c @@ -575,37 +575,6 @@ static const struct r600_reg cayman_context_reg_list[] = { {R_028EAC_CB_COLOR11_DIM, 0, 0}, }; -/* SHADER SAMPLER BORDER EG/CM */ -static int evergreen_state_sampler_border_init(struct r600_context *ctx, uint32_t offset, unsigned id) -{ - struct r600_reg r600_shader_sampler_border[] = { - {R_00A400_TD_PS_SAMPLER0_BORDER_INDEX, 0, 0}, - {R_00A404_TD_PS_SAMPLER0_BORDER_RED, 0, 0}, - {R_00A408_TD_PS_SAMPLER0_BORDER_GREEN, 0, 0}, - {R_00A40C_TD_PS_SAMPLER0_BORDER_BLUE, 0, 0}, - {R_00A410_TD_PS_SAMPLER0_BORDER_ALPHA, 0, 0}, - }; - unsigned nreg = Elements(r600_shader_sampler_border); - unsigned fake_offset = (offset - R_00A400_TD_PS_SAMPLER0_BORDER_INDEX) * 0x100 + 0x40000 + id * 0x1C; - struct r600_range *range; - struct r600_block *block; - int r; - - for (int i = 0; i < nreg; i++) { - r600_shader_sampler_border[i].offset -= R_00A400_TD_PS_SAMPLER0_BORDER_INDEX; - r600_shader_sampler_border[i].offset += fake_offset; - } - r = r600_context_add_block(ctx, r600_shader_sampler_border, nreg, PKT3_SET_CONFIG_REG, 0); - if (r) { - return r; - } - /* set proper offset */ - range = &ctx->range[CTX_RANGE_ID(r600_shader_sampler_border[0].offset)]; - block = range->blocks[CTX_BLOCK_ID(r600_shader_sampler_border[0].offset)]; - block->pm4[1] = (offset - EVERGREEN_CONFIG_REG_OFFSET) >> 2; - return 0; -} - static int evergreen_loop_const_init(struct r600_context *ctx, uint32_t offset) { unsigned nreg = 32; @@ -646,32 +615,6 @@ int evergreen_context_init(struct r600_context *ctx) if (r) goto out_err; - - /* PS SAMPLER */ - for (int j = 0, offset = 0; j < 18; j++, offset += 0xC) { - r = r600_state_sampler_init(ctx, offset); - if (r) - goto out_err; - } - /* VS SAMPLER */ - for (int j = 0, offset = 0xD8; j < 18; j++, offset += 0xC) { - r = r600_state_sampler_init(ctx, offset); - if (r) - goto out_err; - } - /* PS SAMPLER BORDER */ - for (int j = 0; j < 18; j++) { - r = evergreen_state_sampler_border_init(ctx, R_00A400_TD_PS_SAMPLER0_BORDER_INDEX, j); - if (r) - goto out_err; - } - /* VS SAMPLER BORDER */ - for (int j = 0; j < 18; j++) { - r = evergreen_state_sampler_border_init(ctx, R_00A414_TD_VS_SAMPLER0_BORDER_INDEX, j); - if (r) - goto out_err; - } - /* PS loop const */ evergreen_loop_const_init(ctx, 0); /* VS loop const */ @@ -688,66 +631,6 @@ out_err: return r; } -static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset, unsigned id) -{ - unsigned fake_offset = (offset - R_00A400_TD_PS_SAMPLER0_BORDER_INDEX) * 0x100 + 0x40000 + id * 0x1C; - struct r600_range *range; - struct r600_block *block; - int i; - int dirty; - - range = &ctx->range[CTX_RANGE_ID(fake_offset)]; - block = range->blocks[CTX_BLOCK_ID(fake_offset)]; - 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) { - return; - } - - dirty = block->status & R600_BLOCK_STATUS_DIRTY; - if (block->reg[0] != id) { - block->reg[0] = id; - dirty |= R600_BLOCK_STATUS_DIRTY; - } - - for (i = 1; i < 5; i++) { - if (block->reg[i] != state->regs[i + 2].value) { - block->reg[i] = state->regs[i + 2].value; - dirty |= R600_BLOCK_STATUS_DIRTY; - } - } - - /* We have to flush the shaders before we change the border color - * registers, or previous draw commands that haven't completed yet - * will end up using the new border color. */ - if (dirty & R600_BLOCK_STATUS_DIRTY) - r600_context_ps_partial_flush(ctx); - 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) -{ - unsigned offset; - - offset = R_03C000_SQ_TEX_SAMPLER_WORD0_0 + 12*id; - r600_context_pipe_state_set_sampler(ctx, state, offset); - evergreen_context_pipe_state_set_sampler_border(ctx, state, R_00A400_TD_PS_SAMPLER0_BORDER_INDEX, id); -} - -void evergreen_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id) -{ - unsigned offset; - - offset = R_03C000_SQ_TEX_SAMPLER_WORD0_0 + 12*(id + 18); - r600_context_pipe_state_set_sampler(ctx, state, offset); - evergreen_context_pipe_state_set_sampler_border(ctx, state, R_00A414_TD_VS_SAMPLER0_BORDER_INDEX, id); -} - void evergreen_flush_vgt_streamout(struct r600_context *ctx) { struct radeon_winsys_cs *cs = ctx->cs; diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 340036c647c..67ae7d3c04c 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -911,43 +911,47 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, static void *evergreen_create_sampler_state(struct pipe_context *ctx, const struct pipe_sampler_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state); union util_color uc; unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 2 : 0; - if (rstate == NULL) { + if (ss == NULL) { return NULL; } - rstate->id = R600_PIPE_STATE_SAMPLER; + /* directly into sampler avoid r6xx code to emit useless reg */ + ss->seamless_cube_map = false; util_pack_color(state->border_color.f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); - r600_pipe_state_add_reg_noblock(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, - S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | - S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | - S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | - S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter) | aniso_flag_offset) | - S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter) | aniso_flag_offset) | - S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | - S_03C000_MAX_ANISO(r600_tex_aniso_filter(state->max_anisotropy)) | - S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | - S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, - S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) | - S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)), - NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, - S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | - (state->seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) | - S_03C008_TYPE(1), - NULL, 0); - + ss->border_color_use = false; + /* R_03C000_SQ_TEX_SAMPLER_WORD0_0 */ + ss->tex_sampler_words[0] = S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | + S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | + S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | + S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter) | aniso_flag_offset) | + S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter) | aniso_flag_offset) | + S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | + S_03C000_MAX_ANISO(r600_tex_aniso_filter(state->max_anisotropy)) | + S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | + S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0); + /* R_03C004_SQ_TEX_SAMPLER_WORD1_0 */ + ss->tex_sampler_words[1] = S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) | + S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)); + /* R_03C008_SQ_TEX_SAMPLER_WORD2_0 */ + ss->tex_sampler_words[2] = S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | + (state->seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) | + S_03C008_TYPE(1); if (uc.ui) { - r600_pipe_state_add_reg_noblock(rstate, R_00A404_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color.f[0]), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_00A408_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color.f[1]), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_00A40C_TD_PS_SAMPLER0_BORDER_BLUE, fui(state->border_color.f[2]), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_00A410_TD_PS_SAMPLER0_BORDER_ALPHA, fui(state->border_color.f[3]), NULL, 0); - } - return rstate; + ss->border_color_use = true; + /* R_00A400_TD_PS_SAMPLER0_BORDER_RED */ + ss->border_color[0] = fui(state->border_color.f[0]); + /* R_00A404_TD_PS_SAMPLER0_BORDER_GREEN */ + ss->border_color[1] = fui(state->border_color.f[1]); + /* R_00A408_TD_PS_SAMPLER0_BORDER_BLUE */ + ss->border_color[2] = fui(state->border_color.f[2]); + /* R_00A40C_TD_PS_SAMPLER0_BORDER_ALPHA */ + ss->border_color[3] = fui(state->border_color.f[3]); + } + return ss; } static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_context *ctx, @@ -1092,37 +1096,6 @@ static void evergreen_set_ps_sampler_views(struct pipe_context *ctx, unsigned co r600_set_sampler_views(rctx, &rctx->ps_samplers, count, views); } -static void evergreen_bind_samplers(struct r600_context *rctx, - struct r600_textures_info *dst, - unsigned count, void **states, - void (*set_sampler)(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id)) -{ - struct r600_pipe_sampler_state **rstates = (struct r600_pipe_sampler_state**)states; - - for (int i = 0; i < count; i++) { - if (rstates[i] != dst->samplers[i]) { - set_sampler(rctx, &rstates[i]->rstate, i); - } - } - - memcpy(dst->samplers, states, sizeof(void*) * count); - dst->n_samplers = count; -} - -static void evergreen_bind_ps_samplers(struct pipe_context *ctx, unsigned count, void **states) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - evergreen_bind_samplers(rctx, &rctx->ps_samplers, count, states, - evergreen_context_pipe_state_set_ps_sampler); -} - -static void evergreen_bind_vs_samplers(struct pipe_context *ctx, unsigned count, void **states) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - evergreen_bind_samplers(rctx, &rctx->vs_samplers, count, states, - evergreen_context_pipe_state_set_vs_sampler); -} - static void evergreen_set_clip_state(struct pipe_context *ctx, const struct pipe_clip_state *state) { @@ -1822,6 +1795,41 @@ static void evergreen_emit_ps_sampler_views(struct r600_context *rctx, struct r6 evergreen_emit_sampler_views(rctx, &rctx->ps_samplers.views, R600_MAX_CONST_BUFFERS); } +static void evergreen_emit_sampler(struct r600_context *rctx, + struct r600_textures_info *texinfo, + unsigned resource_id_base, + unsigned border_index_reg) +{ + struct radeon_winsys_cs *cs = rctx->cs; + unsigned i; + + for (i = 0; i < texinfo->n_samplers; i++) { + + if (texinfo->samplers[i] == NULL) { + continue; + } + r600_write_value(cs, PKT3(PKT3_SET_SAMPLER, 3, 0)); + r600_write_value(cs, (resource_id_base + i) * 3); + r600_write_array(cs, 3, texinfo->samplers[i]->tex_sampler_words); + + if (texinfo->samplers[i]->border_color_use) { + r600_write_config_reg_seq(cs, border_index_reg, 5); + r600_write_value(cs, i); + r600_write_array(cs, 4, texinfo->samplers[i]->border_color); + } + } +} + +static void evergreen_emit_vs_sampler(struct r600_context *rctx, struct r600_atom *atom) +{ + evergreen_emit_sampler(rctx, &rctx->vs_samplers, 18, R_00A414_TD_VS_SAMPLER0_BORDER_INDEX); +} + +static void evergreen_emit_ps_sampler(struct r600_context *rctx, struct r600_atom *atom) +{ + evergreen_emit_sampler(rctx, &rctx->ps_samplers, 0, R_00A400_TD_PS_SAMPLER0_BORDER_INDEX); +} + void evergreen_init_state_functions(struct r600_context *rctx) { r600_init_atom(&rctx->cb_misc_state.atom, evergreen_emit_cb_misc_state, 0, 0); @@ -1835,6 +1843,8 @@ void evergreen_init_state_functions(struct r600_context *rctx) r600_init_atom(&rctx->vs_samplers.views.atom, evergreen_emit_vs_sampler_views, 0, 0); r600_init_atom(&rctx->ps_samplers.views.atom, evergreen_emit_ps_sampler_views, 0, 0); r600_init_atom(&rctx->cs_shader_state.atom, evergreen_emit_cs_shader, 0, 0); + r600_init_atom(&rctx->vs_samplers.atom_sampler, evergreen_emit_vs_sampler, 0, 0); + r600_init_atom(&rctx->ps_samplers.atom_sampler, evergreen_emit_ps_sampler, 0, 0); rctx->context.create_blend_state = evergreen_create_blend_state; rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state; @@ -1846,17 +1856,17 @@ void evergreen_init_state_functions(struct r600_context *rctx) rctx->context.create_vs_state = r600_create_shader_state_vs; rctx->context.bind_blend_state = r600_bind_blend_state; rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; - rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_samplers; + rctx->context.bind_fragment_sampler_states = r600_bind_ps_samplers; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements; - rctx->context.bind_vertex_sampler_states = evergreen_bind_vs_samplers; + rctx->context.bind_vertex_sampler_states = r600_bind_vs_samplers; rctx->context.bind_vs_state = r600_bind_vs_shader; rctx->context.delete_blend_state = r600_delete_state; rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; rctx->context.delete_fs_state = r600_delete_ps_shader; rctx->context.delete_rasterizer_state = r600_delete_rs_state; - rctx->context.delete_sampler_state = r600_delete_state; + rctx->context.delete_sampler_state = r600_delete_sampler; rctx->context.delete_vertex_elements_state = r600_delete_vertex_element; rctx->context.delete_vs_state = r600_delete_vs_shader; rctx->context.set_blend_color = r600_set_blend_color; diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 14993569d17..1c8bd243256 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -182,6 +182,7 @@ struct r600_so_target { #define R600_CONTEXT_DRAW_PENDING (1 << 0) #define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1) +#define R600_PARTIAL_FLUSH (1 << 2) struct r600_context; struct r600_screen; @@ -191,8 +192,6 @@ int r600_context_init(struct r600_context *ctx); void r600_context_fini(struct r600_context *ctx); void r600_context_pipe_state_emit(struct r600_context *ctx, struct r600_pipe_state *state, unsigned pkt_flags); void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_state *state); -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, unsigned flags); void r600_context_emit_fence(struct r600_context *ctx, struct r600_resource *fence, @@ -208,8 +207,6 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw, boolean count void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *block, unsigned pkt_flags); int evergreen_context_init(struct r600_context *ctx); -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); void _r600_pipe_state_add_reg_bo(struct r600_context *ctx, struct r600_pipe_state *state, diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 017e60d20fd..a5e330f391d 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -241,7 +241,6 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, static const struct r600_reg r600_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0}, {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0}, - {R_009508_TA_CNTL_AUX, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0}, }; static const struct r600_reg r600_ctl_const_list[] = { @@ -506,39 +505,6 @@ static const struct r600_reg r600_context_reg_list[] = { {R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, 0, 0}, }; -/* SHADER SAMPLER R600/R700/EG/CM */ -int r600_state_sampler_init(struct r600_context *ctx, uint32_t offset) -{ - struct r600_reg r600_shader_sampler[] = { - {R_03C000_SQ_TEX_SAMPLER_WORD0_0, 0, 0}, - {R_03C004_SQ_TEX_SAMPLER_WORD1_0, 0, 0}, - {R_03C008_SQ_TEX_SAMPLER_WORD2_0, 0, 0}, - }; - unsigned nreg = Elements(r600_shader_sampler); - - for (int i = 0; i < nreg; i++) { - r600_shader_sampler[i].offset += offset; - } - return r600_context_add_block(ctx, r600_shader_sampler, nreg, PKT3_SET_SAMPLER, R600_SAMPLER_OFFSET); -} - -/* SHADER SAMPLER BORDER R600/R700 */ -static int r600_state_sampler_border_init(struct r600_context *ctx, uint32_t offset) -{ - struct r600_reg r600_shader_sampler_border[] = { - {R_00A400_TD_PS_SAMPLER0_BORDER_RED, 0, 0}, - {R_00A404_TD_PS_SAMPLER0_BORDER_GREEN, 0, 0}, - {R_00A408_TD_PS_SAMPLER0_BORDER_BLUE, 0, 0}, - {R_00A40C_TD_PS_SAMPLER0_BORDER_ALPHA, 0, 0}, - }; - unsigned nreg = Elements(r600_shader_sampler_border); - - for (int i = 0; i < nreg; i++) { - r600_shader_sampler_border[i].offset += offset; - } - return r600_context_add_block(ctx, r600_shader_sampler_border, nreg, PKT3_SET_CONFIG_REG, R600_CONFIG_REG_OFFSET); -} - static int r600_loop_const_init(struct r600_context *ctx, uint32_t offset) { unsigned nreg = 32; @@ -631,32 +597,6 @@ int r600_context_init(struct r600_context *ctx) if (r) goto out_err; - /* PS SAMPLER BORDER */ - for (int j = 0, offset = 0; j < 18; j++, offset += 0x10) { - r = r600_state_sampler_border_init(ctx, offset); - if (r) - goto out_err; - } - - /* VS SAMPLER BORDER */ - for (int j = 0, offset = 0x200; j < 18; j++, offset += 0x10) { - r = r600_state_sampler_border_init(ctx, offset); - if (r) - goto out_err; - } - /* PS SAMPLER */ - for (int j = 0, offset = 0; j < 18; j++, offset += 0xC) { - r = r600_state_sampler_init(ctx, offset); - if (r) - goto out_err; - } - /* VS SAMPLER */ - for (int j = 0, offset = 0xD8; j < 18; j++, offset += 0xC) { - r = r600_state_sampler_init(ctx, offset); - if (r) - goto out_err; - } - /* PS loop const */ r600_loop_const_init(ctx, 0); /* VS loop const */ @@ -836,89 +776,6 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat } } -void r600_context_pipe_state_set_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset) -{ - struct r600_range *range; - struct r600_block *block; - int i; - int dirty; - - 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); - LIST_DELINIT(&block->list); - LIST_DELINIT(&block->enable_list); - return; - } - dirty = block->status & R600_BLOCK_STATUS_DIRTY; - - for (i = 0; i < 3; i++) { - if (block->reg[i] != state->regs[i].value) { - block->reg[i] = state->regs[i].value; - dirty |= R600_BLOCK_STATUS_DIRTY; - } - } - - if (dirty) - r600_context_dirty_block(ctx, block, dirty, 2); -} - -static inline void r600_context_pipe_state_set_sampler_border(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset) -{ - struct r600_range *range; - struct r600_block *block; - int i; - int dirty; - - 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); - LIST_DELINIT(&block->list); - LIST_DELINIT(&block->enable_list); - return; - } - if (state->nregs <= 3) { - return; - } - dirty = block->status & R600_BLOCK_STATUS_DIRTY; - for (i = 0; i < 4; i++) { - if (block->reg[i] != state->regs[i + 3].value) { - block->reg[i] = state->regs[i + 3].value; - dirty |= R600_BLOCK_STATUS_DIRTY; - } - } - - /* We have to flush the shaders before we change the border color - * registers, or previous draw commands that haven't completed yet - * will end up using the new border color. */ - if (dirty & R600_BLOCK_STATUS_DIRTY) - r600_context_ps_partial_flush(ctx); - 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) -{ - unsigned offset; - - offset = R_03C000_SQ_TEX_SAMPLER_WORD0_0 + 12*id; - r600_context_pipe_state_set_sampler(ctx, state, offset); - offset = R_00A400_TD_PS_SAMPLER0_BORDER_RED + 16*id; - r600_context_pipe_state_set_sampler_border(ctx, state, offset); -} - -void r600_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id) -{ - unsigned offset; - - offset = R_03C000_SQ_TEX_SAMPLER_WORD0_0 + 12*(id + 18); - r600_context_pipe_state_set_sampler(ctx, state, offset); - offset = R_00A600_TD_VS_SAMPLER0_BORDER_RED + 16*id; - r600_context_pipe_state_set_sampler_border(ctx, state, offset); -} - /** * @param pkt_flags should be set to RADEON_CP_PACKET3_COMPUTE_MODE if this * block will be used for compute shaders. @@ -1091,6 +948,12 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags) r600_atom_dirty(ctx, &ctx->alphatest_state.atom); r600_atom_dirty(ctx, &ctx->cb_misc_state.atom); r600_atom_dirty(ctx, &ctx->db_misc_state.atom); + /* reemit sampler, will only matter if atom_sampler.num_dw != 0 */ + r600_atom_dirty(ctx, &ctx->vs_samplers.atom_sampler); + r600_atom_dirty(ctx, &ctx->ps_samplers.atom_sampler); + if (ctx->chip_class <= R700) { + r600_atom_dirty(ctx, &ctx->seamless_cube_map.atom); + } ctx->vertex_buffer_state.dirty_mask = ctx->vertex_buffer_state.enabled_mask; r600_vertex_buffers_dirty(ctx); diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index f41fa8fc7f6..04641838e0b 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -240,15 +240,21 @@ struct r600_pipe_shader { }; struct r600_pipe_sampler_state { - struct r600_pipe_state rstate; - boolean seamless_cube_map; + uint32_t tex_sampler_words[3]; + uint32_t border_color[4]; + bool border_color_use; + bool seamless_cube_map; }; /* needed for blitter save */ #define NUM_TEX_UNITS 16 -struct r600_samplerview_state -{ +struct r600_seamless_cube_map { + struct r600_atom atom; + bool enabled; +}; + +struct r600_samplerview_state { struct r600_atom atom; struct r600_pipe_sampler_view *views[NUM_TEX_UNITS]; uint32_t enabled_mask; @@ -258,17 +264,16 @@ struct r600_samplerview_state struct r600_textures_info { struct r600_samplerview_state views; - + struct r600_atom atom_sampler; struct r600_pipe_sampler_state *samplers[NUM_TEX_UNITS]; unsigned n_samplers; - bool samplers_dirty; bool is_array_sampler[NUM_TEX_UNITS]; }; struct r600_fence { struct pipe_reference reference; unsigned index; /* in the shared bo */ - struct r600_resource *sleep_bo; + struct r600_resource *sleep_bo; struct list_head head; }; @@ -367,6 +372,7 @@ struct r600_context { struct r600_constbuf_state ps_constbuf_state; struct r600_textures_info vs_samplers; struct r600_textures_info ps_samplers; + struct r600_seamless_cube_map seamless_cube_map; struct r600_cs_shader_state cs_shader_state; struct radeon_winsys_cs *cs; @@ -502,7 +508,6 @@ void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader /* r600_state.c */ void r600_set_scissor_state(struct r600_context *rctx, const struct pipe_scissor_state *state); -void r600_update_sampler_states(struct r600_context *rctx); void r600_init_state_functions(struct r600_context *rctx); void r600_init_atom_start_cs(struct r600_context *rctx); void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); @@ -550,6 +555,8 @@ void r600_set_sampler_views(struct r600_context *rctx, struct r600_textures_info *dst, unsigned count, struct pipe_sampler_view **views); +void r600_bind_vs_samplers(struct pipe_context *ctx, unsigned count, void **states); +void r600_bind_ps_samplers(struct pipe_context *ctx, unsigned count, void **states); void *r600_create_vertex_elements(struct pipe_context *ctx, unsigned count, const struct pipe_vertex_element *elements); @@ -563,6 +570,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state); void r600_delete_rs_state(struct pipe_context *ctx, void *state); void r600_sampler_view_destroy(struct pipe_context *ctx, struct pipe_sampler_view *state); +void r600_delete_sampler(struct pipe_context *ctx, void *state); void r600_delete_state(struct pipe_context *ctx, void *state); void r600_bind_vertex_elements(struct pipe_context *ctx, void *state); void *r600_create_shader_state_ps(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 842808a990b..9c7ff7febb5 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -932,7 +932,6 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, const struct pipe_sampler_state *state) { struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state); - struct r600_pipe_state *rstate; union util_color uc; unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 4 : 0; @@ -941,31 +940,36 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, } ss->seamless_cube_map = state->seamless_cube_map; - rstate = &ss->rstate; - rstate->id = R600_PIPE_STATE_SAMPLER; + ss->border_color_use = false; util_pack_color(state->border_color.f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); - r600_pipe_state_add_reg_noblock(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, - S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | - S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | - S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | - S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter) | aniso_flag_offset) | - S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter) | aniso_flag_offset) | - S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | - S_03C000_MAX_ANISO(r600_tex_aniso_filter(state->max_anisotropy)) | - S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | - S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, - S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | - S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | - S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_TYPE(1), NULL, 0); + /* R_03C000_SQ_TEX_SAMPLER_WORD0_0 */ + ss->tex_sampler_words[0] = S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | + S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | + S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | + S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter) | aniso_flag_offset) | + S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter) | aniso_flag_offset) | + S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | + S_03C000_MAX_ANISO(r600_tex_aniso_filter(state->max_anisotropy)) | + S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | + S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0); + /* R_03C004_SQ_TEX_SAMPLER_WORD1_0 */ + ss->tex_sampler_words[1] = S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | + S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | + S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)); + /* R_03C008_SQ_TEX_SAMPLER_WORD2_0 */ + ss->tex_sampler_words[2] = S_03C008_TYPE(1); if (uc.ui) { - r600_pipe_state_add_reg_noblock(rstate, R_00A400_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color.f[0]), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_00A404_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color.f[1]), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_00A408_TD_PS_SAMPLER0_BORDER_BLUE, fui(state->border_color.f[2]), NULL, 0); - r600_pipe_state_add_reg_noblock(rstate, R_00A40C_TD_PS_SAMPLER0_BORDER_ALPHA, fui(state->border_color.f[3]), NULL, 0); - } - return rstate; + ss->border_color_use = true; + /* R_00A400_TD_PS_SAMPLER0_BORDER_RED */ + ss->border_color[0] = fui(state->border_color.f[0]); + /* R_00A404_TD_PS_SAMPLER0_BORDER_GREEN */ + ss->border_color[1] = fui(state->border_color.f[1]); + /* R_00A408_TD_PS_SAMPLER0_BORDER_BLUE */ + ss->border_color[2] = fui(state->border_color.f[2]); + /* R_00A40C_TD_PS_SAMPLER0_BORDER_ALPHA */ + ss->border_color[3] = fui(state->border_color.f[3]); + } + return ss; } static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, @@ -1086,93 +1090,6 @@ static void r600_set_ps_sampler_views(struct pipe_context *ctx, unsigned count, r600_set_sampler_views(rctx, &rctx->ps_samplers, count, views); } -static void r600_set_seamless_cubemap(struct r600_context *rctx, boolean enable) -{ - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); - if (rstate == NULL) - return; - - rstate->id = R600_PIPE_STATE_SEAMLESS_CUBEMAP; - r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, - (enable ? 0 : S_009508_DISABLE_CUBE_WRAP(1)) | - S_009508_DISABLE_CUBE_ANISO(1) | - S_009508_SYNC_GRADIENT(1) | - S_009508_SYNC_WALKER(1) | - S_009508_SYNC_ALIGNER(1)); - - free(rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP]); - rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP] = rstate; - r600_context_pipe_state_set(rctx, rstate); -} - -static void r600_bind_samplers(struct r600_context *rctx, - struct r600_textures_info *dst, - unsigned count, void **states) -{ - memcpy(dst->samplers, states, sizeof(void*) * count); - dst->n_samplers = count; - dst->samplers_dirty = true; -} - -static void r600_bind_vs_samplers(struct pipe_context *ctx, unsigned count, void **states) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - r600_bind_samplers(rctx, &rctx->vs_samplers, count, states); -} - -static void r600_bind_ps_samplers(struct pipe_context *ctx, unsigned count, void **states) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - r600_bind_samplers(rctx, &rctx->ps_samplers, count, states); -} - -static void r600_update_samplers(struct r600_context *rctx, - struct r600_textures_info *tex, - void (*set_sampler)(struct r600_context*, struct r600_pipe_state*, unsigned)) -{ - unsigned i; - - if (tex->samplers_dirty) { - int seamless = -1; - for (i = 0; i < tex->n_samplers; i++) { - if (!tex->samplers[i]) - continue; - - /* TEX_ARRAY_OVERRIDE must be set for array textures to disable - * filtering between layers. - * Don't update TEX_ARRAY_OVERRIDE if we don't have the sampler view. */ - if (tex->views.views[i]) { - if (tex->views.views[i]->base.texture->target == PIPE_TEXTURE_1D_ARRAY || - tex->views.views[i]->base.texture->target == PIPE_TEXTURE_2D_ARRAY) { - tex->samplers[i]->rstate.regs[0].value |= S_03C000_TEX_ARRAY_OVERRIDE(1); - tex->is_array_sampler[i] = true; - } else { - tex->samplers[i]->rstate.regs[0].value &= C_03C000_TEX_ARRAY_OVERRIDE; - tex->is_array_sampler[i] = false; - } - } - - set_sampler(rctx, &tex->samplers[i]->rstate, i); - - if (tex->samplers[i]) - seamless = tex->samplers[i]->seamless_cube_map; - } - - if (seamless != -1) - r600_set_seamless_cubemap(rctx, seamless); - - tex->samplers_dirty = false; - } -} - -void r600_update_sampler_states(struct r600_context *rctx) -{ - r600_update_samplers(rctx, &rctx->vs_samplers, - r600_context_pipe_state_set_vs_sampler); - r600_update_samplers(rctx, &rctx->ps_samplers, - r600_context_pipe_state_set_ps_sampler); -} - static void r600_set_clip_state(struct pipe_context *ctx, const struct pipe_clip_state *state) { @@ -1764,8 +1681,79 @@ static void r600_emit_ps_sampler_views(struct r600_context *rctx, struct r600_at r600_emit_sampler_views(rctx, &rctx->ps_samplers.views, R600_MAX_CONST_BUFFERS); } +static void r600_emit_sampler(struct r600_context *rctx, + struct r600_textures_info *texinfo, + unsigned resource_id_base, + unsigned border_color_reg) +{ + struct radeon_winsys_cs *cs = rctx->cs; + unsigned i; + + for (i = 0; i < texinfo->n_samplers; i++) { + + if (texinfo->samplers[i] == NULL) { + continue; + } + + /* TEX_ARRAY_OVERRIDE must be set for array textures to disable + * filtering between layers. + * Don't update TEX_ARRAY_OVERRIDE if we don't have the sampler view. + */ + if (texinfo->views.views[i]) { + if (texinfo->views.views[i]->base.texture->target == PIPE_TEXTURE_1D_ARRAY || + texinfo->views.views[i]->base.texture->target == PIPE_TEXTURE_2D_ARRAY) { + texinfo->samplers[i]->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1); + texinfo->is_array_sampler[i] = true; + } else { + texinfo->samplers[i]->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE; + texinfo->is_array_sampler[i] = false; + } + } + + r600_write_value(cs, PKT3(PKT3_SET_SAMPLER, 3, 0)); + r600_write_value(cs, (resource_id_base + i) * 3); + r600_write_array(cs, 3, texinfo->samplers[i]->tex_sampler_words); + + if (texinfo->samplers[i]->border_color_use) { + unsigned offset; + + offset = border_color_reg; + offset += i * 16; + r600_write_config_reg_seq(cs, offset, 4); + r600_write_array(cs, 4, texinfo->samplers[i]->border_color); + } + } +} + +static void r600_emit_vs_sampler(struct r600_context *rctx, struct r600_atom *atom) +{ + r600_emit_sampler(rctx, &rctx->vs_samplers, 18, R_00A600_TD_VS_SAMPLER0_BORDER_RED); +} + +static void r600_emit_ps_sampler(struct r600_context *rctx, struct r600_atom *atom) +{ + r600_emit_sampler(rctx, &rctx->ps_samplers, 0, R_00A400_TD_PS_SAMPLER0_BORDER_RED); +} + +static void r600_emit_seamless_cube_map(struct r600_context *rctx, struct r600_atom *atom) +{ + struct radeon_winsys_cs *cs = rctx->cs; + unsigned tmp; + + tmp = S_009508_DISABLE_CUBE_ANISO(1) | + S_009508_SYNC_GRADIENT(1) | + S_009508_SYNC_WALKER(1) | + S_009508_SYNC_ALIGNER(1); + if (!rctx->seamless_cube_map.enabled) { + tmp |= S_009508_DISABLE_CUBE_WRAP(1); + } + r600_write_config_reg(cs, R_009508_TA_CNTL_AUX, tmp); +} + void r600_init_state_functions(struct r600_context *rctx) { + r600_init_atom(&rctx->seamless_cube_map.atom, r600_emit_seamless_cube_map, 3, 0); + r600_atom_dirty(rctx, &rctx->seamless_cube_map.atom); r600_init_atom(&rctx->cb_misc_state.atom, r600_emit_cb_misc_state, 0, 0); r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); r600_init_atom(&rctx->db_misc_state.atom, r600_emit_db_misc_state, 4, 0); @@ -1775,6 +1763,11 @@ void r600_init_state_functions(struct r600_context *rctx) r600_init_atom(&rctx->ps_constbuf_state.atom, r600_emit_ps_constant_buffers, 0, 0); r600_init_atom(&rctx->vs_samplers.views.atom, r600_emit_vs_sampler_views, 0, 0); r600_init_atom(&rctx->ps_samplers.views.atom, r600_emit_ps_sampler_views, 0, 0); + /* sampler must be emited before TA_CNTL_AUX otherwise DISABLE_CUBE_WRAP change + * does not take effect + */ + r600_init_atom(&rctx->vs_samplers.atom_sampler, r600_emit_vs_sampler, 0, EMIT_EARLY); + r600_init_atom(&rctx->ps_samplers.atom_sampler, r600_emit_ps_sampler, 0, EMIT_EARLY); rctx->context.create_blend_state = r600_create_blend_state; rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state; @@ -1796,7 +1789,7 @@ void r600_init_state_functions(struct r600_context *rctx) rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; rctx->context.delete_fs_state = r600_delete_ps_shader; rctx->context.delete_rasterizer_state = r600_delete_rs_state; - rctx->context.delete_sampler_state = r600_delete_state; + rctx->context.delete_sampler_state = r600_delete_sampler; rctx->context.delete_vertex_elements_state = r600_delete_vertex_element; rctx->context.delete_vs_state = r600_delete_vs_shader; rctx->context.set_blend_color = r600_set_blend_color; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index f91f2654f58..4a75c144d8a 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -369,6 +369,59 @@ void r600_sampler_view_destroy(struct pipe_context *ctx, FREE(resource); } +static void r600_bind_samplers(struct r600_context *rctx, + struct r600_textures_info *dst, + unsigned count, void **states) +{ + int seamless_cube_map = -1; + unsigned i; + + memcpy(dst->samplers, states, sizeof(void*) * count); + dst->n_samplers = count; + dst->atom_sampler.num_dw = 0; + + for (i = 0; i < count; i++) { + struct r600_pipe_sampler_state *sampler = states[i]; + + if (sampler == NULL) { + continue; + } + if (sampler->border_color_use) { + dst->atom_sampler.num_dw += 11; + rctx->flags |= R600_PARTIAL_FLUSH; + } else { + dst->atom_sampler.num_dw += 5; + } + seamless_cube_map = sampler->seamless_cube_map; + } + if (rctx->chip_class <= R700 && seamless_cube_map != -1 && seamless_cube_map != rctx->seamless_cube_map.enabled) { + /* change in TA_CNTL_AUX need a pipeline flush */ + rctx->flags |= R600_PARTIAL_FLUSH; + rctx->seamless_cube_map.enabled = seamless_cube_map; + r600_atom_dirty(rctx, &rctx->seamless_cube_map.atom); + } + if (dst->atom_sampler.num_dw) { + r600_atom_dirty(rctx, &dst->atom_sampler); + } +} + +void r600_bind_vs_samplers(struct pipe_context *ctx, unsigned count, void **states) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + r600_bind_samplers(rctx, &rctx->vs_samplers, count, states); +} + +void r600_bind_ps_samplers(struct pipe_context *ctx, unsigned count, void **states) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + r600_bind_samplers(rctx, &rctx->ps_samplers, count, states); +} + +void r600_delete_sampler(struct pipe_context *ctx, void *state) +{ + free(state); +} + void r600_delete_state(struct pipe_context *ctx, void *state) { struct r600_context *rctx = (struct r600_context *)ctx; @@ -532,7 +585,7 @@ void r600_set_sampler_views(struct r600_context *rctx, if (rctx->chip_class <= R700 && (rviews[i]->base.texture->target == PIPE_TEXTURE_1D_ARRAY || rviews[i]->base.texture->target == PIPE_TEXTURE_2D_ARRAY) != dst->is_array_sampler[i]) { - dst->samplers_dirty = true; + r600_atom_dirty(rctx, &dst->atom_sampler); } pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], views[i]); @@ -935,10 +988,6 @@ static void r600_update_derived_state(struct r600_context *rctx) } } - if (rctx->chip_class < EVERGREEN) { - r600_update_sampler_states(rctx); - } - r600_shader_select(ctx, rctx->ps_shader, &ps_dirty); if (rctx->ps_shader && ((rctx->sprite_coord_enable && @@ -1011,6 +1060,13 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) r600_update_derived_state(rctx); + /* partial flush triggered by border color change */ + if (rctx->flags & R600_PARTIAL_FLUSH) { + rctx->flags &= ~R600_PARTIAL_FLUSH; + r600_write_value(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); + r600_write_value(cs, EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4)); + } + if (info.indexed) { /* Initialize the index buffer struct. */ pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer); -- 2.30.2