The Gallium state bit is part of pipe_rasterizer_state, but the hardware state is per-sampler. The idea here is to change the state bit in sampler state registers based on the currently-bound rasterizer state. --- src/gallium/drivers/r600/evergreen_state.c | 45 +++++++++++++++++++++++++- src/gallium/drivers/r600/evergreend.h | 9 +++++ src/gallium/drivers/r600/r600_pipe.c | 1 + src/gallium/drivers/r600/r600_pipe.h | 5 ++- src/gallium/drivers/r600/r600_state_common.c | 1 + 5 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index e325361..3e7f64d 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -239,6 +239,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, rstate = &rs->rstate; rs->flatshade = state->flatshade; rs->sprite_coord_enable = state->sprite_coord_enable; + rs->seamless_cube_map = state->seamless_cube_map; clip_rule = state->scissor ? 0xAAAA : 0xFFFF; @@ -478,15 +479,35 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou rctx->ps_samplers.n_views = count; } +static void evergreen_update_seamless_cube_map_state(struct r600_textures_info *tex, + boolean enable) +{ + unsigned i; + + for (i = 0; i < tex->n_samplers; i++) { + if (tex->samplers[i]) { + struct r600_pipe_state *state = tex->samplers[i]; + + /* SQ_TEX_SAMPLER_WORD2_0 is at index 2. */ + if (enable) { + state->regs[2].value &= C_03C008_DISABLE_CUBE_WRAP; + } else { + state->regs[2].value |= S_03C008_DISABLE_CUBE_WRAP(1); + } + } + } +} + static void evergreen_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_state **rstates = (struct r600_pipe_state **)states; - memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count); rctx->ps_samplers.n_samplers = count; + evergreen_update_seamless_cube_map_state(&rctx->ps_samplers, rctx->seamless_cube_map); + for (int i = 0; i < count; i++) { evergreen_context_pipe_state_set_ps_sampler(&rctx->ctx, rstates[i], i); } @@ -497,11 +518,33 @@ static void evergreen_bind_vs_sampler(struct pipe_context *ctx, unsigned count, struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_state **rstates = (struct r600_pipe_state **)states; + memcpy(rctx->vs_samplers.samplers, states, sizeof(void*) * count); + rctx->vs_samplers.n_samplers = count; + + evergreen_update_seamless_cube_map_state(&rctx->vs_samplers, rctx->seamless_cube_map); + for (int i = 0; i < count; i++) { evergreen_context_pipe_state_set_vs_sampler(&rctx->ctx, rstates[i], i); } } +void evergreen_set_seamless_cube_map(struct r600_pipe_context *rctx, boolean enable) +{ + if (rctx->seamless_cube_map != enable) { + rctx->seamless_cube_map = enable; + + evergreen_update_seamless_cube_map_state(&rctx->ps_samplers, enable); + evergreen_update_seamless_cube_map_state(&rctx->vs_samplers, enable); + + evergreen_bind_ps_sampler(&rctx->context, + rctx->ps_samplers.n_samplers, + rctx->ps_samplers.samplers); + evergreen_bind_vs_sampler(&rctx->context, + rctx->vs_samplers.n_samplers, + rctx->vs_samplers.samplers); + } +} + static void evergreen_set_clip_state(struct pipe_context *ctx, const struct pipe_clip_state *state) { diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index de445b8..670606d 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1194,6 +1194,15 @@ #define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 21) #define G_03C008_FORCE_DEGAMMA(x) (((x) >> 21) & 0x1) #define C_03C008_FORCE_DEGAMMA 0xFFDFFFFF +#define S_03C008_ANISO_BIAS(x) (((x) & 0x3f) << 22) +#define G_03C008_ANISO_BIAS(x) (((x) >> 22) & 0x3f) +#define C_03C008_ANISO_BIAS (~(0x3f << 22)) +#define S_03C008_TRUNCATE_COORD(x) (((x) & 0x1) << 28) +#define G_03C008_TRUNCATE_COORD(x) (((x) >> 28) & 0x1) +#define C_03C008_TRUNCATE_COORD (~(1 << 28)) +#define S_03C008_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 29) +#define G_03C008_DISABLE_CUBE_WRAP(x) (((x) >> 29) & 0x1) +#define C_03C008_DISABLE_CUBE_WRAP (~(1 << 29)) #define S_03C008_TYPE(x) (((x) & 0x1) << 31) #define G_03C008_TYPE(x) (((x) >> 31) & 0x1) #define C_03C008_TYPE 0x7FFFFFFF diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index e28d834..677d42b 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -373,6 +373,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: + case PIPE_CAP_SEAMLESS_CUBE_MAP: return 1; case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_INDEP_BLEND_FUNC: diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index ae2a57e..55b836e 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -87,6 +87,7 @@ struct r600_pipe_sampler_view { struct r600_pipe_rasterizer { struct r600_pipe_state rstate; bool flatshade; + boolean seamless_cube_map; unsigned sprite_coord_enable; float offset_units; float offset_scale; @@ -186,7 +187,8 @@ struct r600_pipe_context { /* shader information */ unsigned sprite_coord_enable; bool flatshade; - struct r600_textures_info ps_samplers; + boolean seamless_cube_map; + struct r600_textures_info ps_samplers, vs_samplers; struct r600_pipe_fences fences; @@ -216,6 +218,7 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride); +void evergreen_set_seamless_cube_map(struct r600_pipe_context *rctx, boolean enable); /* r600_blit.c */ void r600_init_blit_functions(struct r600_pipe_context *rctx); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index cf605e1..591b2ef 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -103,6 +103,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state) if (rctx->family >= CHIP_CEDAR) { evergreen_polygon_offset_update(rctx); + evergreen_set_seamless_cube_map(rctx, rs->seamless_cube_map); } else { r600_polygon_offset_update(rctx); } -- 1.7.4.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev