*
**************************************************************************/
+#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_pstipple.h"
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
#include "draw/draw_vertex.h"
static void
-update_fragment_shader(struct softpipe_context *softpipe)
+update_fragment_shader(struct softpipe_context *softpipe, unsigned prim)
{
struct sp_fragment_shader_variant_key key;
memset(&key, 0, sizeof(key));
+ if (prim == PIPE_PRIM_TRIANGLES)
+ key.polygon_stipple = softpipe->rasterizer->poly_stipple_enable;
+
if (softpipe->fs) {
softpipe->fs_variant = softpipe_find_fs_variant(softpipe,
softpipe->fs, &key);
}
+/**
+ * This should be called when the polygon stipple pattern changes.
+ * We create a new texture from the stipple pattern and create a new
+ * sampler view.
+ */
+static void
+update_polygon_stipple_pattern(struct softpipe_context *softpipe)
+{
+ struct pipe_resource *tex;
+ struct pipe_sampler_view *view;
+
+ tex = util_pstipple_create_stipple_texture(&softpipe->pipe,
+ softpipe->poly_stipple.stipple);
+ pipe_resource_reference(&softpipe->pstipple.texture, tex);
+
+ view = util_pstipple_create_sampler_view(&softpipe->pipe, tex);
+ pipe_sampler_view_reference(&softpipe->pstipple.sampler_view, view);
+}
+
+
+/**
+ * Should be called when polygon stipple is enabled/disabled or when
+ * the fragment shader changes.
+ * We add/update the fragment sampler and sampler views to sample from
+ * the polygon stipple texture. The texture unit that we use depends on
+ * the fragment shader (we need to use a unit not otherwise used by the
+ * shader).
+ */
+static void
+update_polygon_stipple_enable(struct softpipe_context *softpipe, unsigned prim)
+{
+ if (prim == PIPE_PRIM_TRIANGLES &&
+ softpipe->fs_variant->key.polygon_stipple) {
+ const unsigned unit = softpipe->fs_variant->stipple_sampler_unit;
+
+ assert(unit >= softpipe->num_fragment_samplers);
+
+ /* sampler state */
+ softpipe->fragment_samplers[unit] = softpipe->pstipple.sampler;
+
+ /* sampler view */
+ pipe_sampler_view_reference(&softpipe->fragment_sampler_views[unit],
+ softpipe->pstipple.sampler_view);
+
+ sp_tex_tile_cache_set_sampler_view(softpipe->fragment_tex_cache[unit],
+ softpipe->pstipple.sampler_view);
+
+ softpipe->dirty |= SP_NEW_SAMPLER;
+ }
+}
+
+
/* Hopefully this will remain quite simple, otherwise need to pull in
* something like the state tracker mechanism.
*/
void
-softpipe_update_derived(struct softpipe_context *softpipe)
+softpipe_update_derived(struct softpipe_context *softpipe, unsigned prim)
{
struct softpipe_screen *sp_screen = softpipe_screen(softpipe->pipe.screen);
softpipe->tex_timestamp = sp_screen->timestamp;
softpipe->dirty |= SP_NEW_TEXTURE;
}
-
+
+#if DO_PSTIPPLE_IN_HELPER_MODULE
+ if (softpipe->dirty & SP_NEW_STIPPLE)
+ /* before updating samplers! */
+ update_polygon_stipple_pattern(softpipe);
+#endif
+
if (softpipe->dirty & (SP_NEW_RASTERIZER |
SP_NEW_FS))
- update_fragment_shader(softpipe);
+ update_fragment_shader(softpipe, prim);
+
+#if DO_PSTIPPLE_IN_HELPER_MODULE
+ if (softpipe->dirty & (SP_NEW_RASTERIZER |
+ SP_NEW_STIPPLE |
+ SP_NEW_FS))
+ update_polygon_stipple_enable(softpipe, prim);
+#endif
if (softpipe->dirty & (SP_NEW_SAMPLER |
SP_NEW_TEXTURE |