[Mesa-dev] [PATCH] r600g: add polygon stipple support

Marek Olšák maraeo at gmail.com
Sun Feb 1 09:40:46 PST 2015


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 <maraeo at 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 <airlied at gmail.com> wrote:
>> From: Dave Airlie <airlied at 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 <airlied at 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 at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list