One more thing. Polygon stippling should be disabled for lines and points (if a GS is bound, the GS out primitive matters).
BTW, I have sent out a patch that adds the ability to specify a fixed texture slot for u_pstipple. Marek On Sat, Jan 31, 2015 at 1:42 AM, Marek Olšák <mar...@gmail.com> wrote: > Hi Dave, > > R600 supports 18 samplers per shader, so you can use a fixed slot > outside of the API range (16 or 17) and bind the stipple texture > statically there. The motivation is that you won't have to read the > shader to get the slot number, so it will be completely independent. > You don't have to unbind it (except for r600_destroy_context) and you > don't even have to store the texture in r600_context, because nothing > else needs it. The texture can be created and bound in > set_polygon_stipple directly, which can moved to r600_state_common.c. > > It doesn't look like any code can be shared with radeonsi, but it > looks a lot simpler than I expected. > > Marek > > > On Tue, Jan 27, 2015 at 9:04 AM, Dave Airlie <airl...@gmail.com> wrote: >> 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev