From: Dave Airlie <airl...@redhat.com> This use the gallium poly stipple helper to modify the fragment shader and sets up the appropriate state around it.
This renders the polys test from mesa demos properly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=25280 TODO: should this be in radeon common code? (radeonsi) Signed-off-by: Dave Airlie <airl...@redhat.com> --- src/gallium/drivers/r600/evergreen_state.c | 5 ++++- src/gallium/drivers/r600/r600_pipe.c | 6 ++++++ src/gallium/drivers/r600/r600_pipe.h | 8 ++++++++ src/gallium/drivers/r600/r600_shader.c | 11 +++++++++++ src/gallium/drivers/r600/r600_shader.h | 2 ++ src/gallium/drivers/r600/r600_state_common.c | 27 +++++++++++++++++++++++++++ 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index ea58aea..7a0ba7e 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -482,7 +482,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, S_028810_DX_LINEAR_ATTR_CLIP_ENA(1) | S_028810_DX_RASTERIZATION_KILL(state->rasterizer_discard); rs->multisample_enable = state->multisample; - + rs->poly_stipple_enable = state->poly_stipple_enable; /* offset */ rs->offset_units = state->offset_units; rs->offset_scale = state->offset_scale * 12.0f; @@ -864,6 +864,9 @@ static void evergreen_emit_clip_state(struct r600_context *rctx, struct r600_ato static void evergreen_set_polygon_stipple(struct pipe_context *ctx, const struct pipe_poly_stipple *state) { + struct r600_context *rctx = (struct r600_context *)ctx; + rctx->poly_stipple = *state; + rctx->pstipple_update = true; } static void evergreen_get_scissor_rect(struct r600_context *rctx, diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index b6f7859..20cfc25 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -35,6 +35,7 @@ #include "util/u_simple_shaders.h" #include "util/u_upload_mgr.h" #include "util/u_math.h" +#include "util/u_pstipple.h" #include "vl/vl_decoder.h" #include "vl/vl_video_buffer.h" #include "radeon/radeon_video.h" @@ -100,6 +101,10 @@ static void r600_destroy_context(struct pipe_context *context) u_suballocator_destroy(rctx->allocator_fetch_shader); } + if (rctx->pstipple.sampler) + rctx->b.b.delete_sampler_state(&rctx->b.b, rctx->pstipple.sampler); + pipe_resource_reference(&rctx->pstipple.texture, NULL); + pipe_sampler_view_reference(&rctx->pstipple.sampler_view, NULL); r600_release_command_buffer(&rctx->start_cs_cmd); FREE(rctx->start_compute_cs_cmd.buf); @@ -200,6 +205,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void util_blitter_set_texture_multisample(rctx->blitter, rscreen->has_msaa); rctx->blitter->draw_rectangle = r600_draw_rectangle; + rctx->pstipple.sampler = util_pstipple_create_sampler(&rctx->b.b); r600_begin_new_cs(rctx); r600_query_init_backend_mask(&rctx->b); /* this emits commands and must be last */ diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index e110efe..cb910e9 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -264,6 +264,7 @@ struct r600_rasterizer_state { bool offset_enable; bool scissor_enable; bool multisample_enable; + bool poly_stipple_enable; }; struct r600_poly_offset_state { @@ -485,6 +486,13 @@ struct r600_context { void *sb_context; struct r600_isa *isa; + struct pipe_poly_stipple poly_stipple; + bool pstipple_update; + struct { + struct pipe_resource *texture; + struct pipe_sampler_state *sampler; + struct pipe_sampler_view *sampler_view; + } pstipple; }; static INLINE void r600_emit_command_buffer(struct radeon_winsys_cs *cs, diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 16e820e..0bbfe52 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -36,6 +36,7 @@ #include "tgsi/tgsi_dump.h" #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_pstipple.h" #include <stdio.h> #include <errno.h> @@ -1824,7 +1825,13 @@ static int r600_shader_from_tgsi(struct r600_context *rctx, r600_bytecode_init(ctx.bc, rscreen->b.chip_class, rscreen->b.family, rscreen->has_compressed_msaa_texturing); + + if (key.polygon_stipple) + tokens = util_pstipple_create_fragment_shader( + tokens, &ctx.shader->poly_stipple_unit); + ctx.tokens = tokens; + tgsi_scan_shader(tokens, &ctx.info); shader->indirect_files = ctx.info.indirect_files; indirect_gprs = ctx.info.indirect_files & ~(1 << TGSI_FILE_CONSTANT); @@ -2533,10 +2540,14 @@ static int r600_shader_from_tgsi(struct r600_context *rctx, } free(ctx.literals); + if (key.polygon_stipple) + tgsi_free_tokens(tokens); tgsi_parse_free(&ctx.parse); return 0; out_err: free(ctx.literals); + if (key.polygon_stipple) + tgsi_free_tokens(tokens); tgsi_parse_free(&ctx.parse); return r; } diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index b2559e9..7bcc987 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -86,6 +86,7 @@ struct r600_shader { unsigned vs_as_es; unsigned vs_as_gs_a; unsigned ps_prim_id_input; + unsigned poly_stipple_unit; struct r600_shader_array * arrays; }; @@ -96,6 +97,7 @@ struct r600_shader_key { unsigned vs_as_es:1; unsigned vs_as_gs_a:1; unsigned vs_prim_id_out:8; + unsigned polygon_stipple:1; }; struct r600_shader_array { diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index b498d00..a737e1b 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -34,6 +34,7 @@ #include "util/u_upload_mgr.h" #include "util/u_math.h" #include "tgsi/tgsi_parse.h" +#include "util/u_pstipple.h" void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw) { @@ -705,6 +706,7 @@ static INLINE struct r600_shader_key r600_shader_selector_key(struct pipe_contex /* Dual-source blending only makes sense with nr_cbufs == 1. */ if (key.nr_cbufs == 1 && rctx->dual_src_blend) key.nr_cbufs = 2; + key.polygon_stipple = rctx->rasterizer && rctx->rasterizer->poly_stipple_enable; } else if (sel->type == PIPE_SHADER_VERTEX) { key.vs_as_es = (rctx->gs_shader != NULL); if (rctx->ps_shader->current->shader.gs_prim_id_input && !rctx->gs_shader) { @@ -1153,12 +1155,32 @@ static void update_gs_block_state(struct r600_context *rctx, unsigned enable) } } +static void r600_poly_stipple_update(struct r600_context *rctx) +{ + struct pipe_resource *tex; + struct pipe_sampler_view *view; + + tex = util_pstipple_create_stipple_texture(&rctx->b.b, + rctx->poly_stipple.stipple); + pipe_resource_reference(&rctx->pstipple.texture, tex); + pipe_resource_reference(&tex, NULL); + + view = util_pstipple_create_sampler_view(&rctx->b.b, + rctx->pstipple.texture); + pipe_sampler_view_reference(&rctx->pstipple.sampler_view,view); + pipe_sampler_view_reference(&view, NULL); +} + static bool r600_update_derived_state(struct r600_context *rctx) { struct pipe_context * ctx = (struct pipe_context*)rctx; bool ps_dirty = false, vs_dirty = false, gs_dirty = false; bool blend_disable; bool need_buf_const; + + if (rctx->pstipple_update && !rctx->blitter->running) + r600_poly_stipple_update(rctx); + if (!rctx->blitter->running) { unsigned i; @@ -1282,6 +1304,11 @@ static bool r600_update_derived_state(struct r600_context *rctx) /* on R600 we stuff masks + txq info into one constant buffer */ /* on evergreen we only need a txq info one */ if (rctx->ps_shader) { + if (rctx->ps_shader->current->key.polygon_stipple) { + rctx->b.b.set_sampler_views(&rctx->b.b, PIPE_SHADER_FRAGMENT, rctx->ps_shader->current->shader.poly_stipple_unit, 1, &rctx->pstipple.sampler_view); + rctx->b.b.bind_sampler_states(&rctx->b.b, PIPE_SHADER_FRAGMENT, rctx->ps_shader->current->shader.poly_stipple_unit, 1, &rctx->pstipple.sampler); + } + need_buf_const = rctx->ps_shader->current->shader.uses_tex_buffers || rctx->ps_shader->current->shader.has_txq_cube_array_z_comp; if (need_buf_const) { if (rctx->b.chip_class < EVERGREEN) -- 1.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev