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

Reply via email to