mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
softpipe: use the polygon stipple utility module
This is an alternative to the draw module's polygon stipple stage. The softpipe implementation here is just a test. The advantange of using the new polygon stipple utility module (with other drivers) is we can avoid software vertex processing in the draw module and get much better performance. Polygon stipple doesn't require special vertex processing like the other draw module stage.
This commit is contained in:
parent
c534f11164
commit
57aa597b3d
9 changed files with 131 additions and 14 deletions
|
|
@ -60,7 +60,7 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
|
|||
return;
|
||||
|
||||
#if 0
|
||||
softpipe_update_derived(softpipe); /* not needed?? */
|
||||
softpipe_update_derived(softpipe, PIPE_PRIM_TRIANGLES); /* not needed?? */
|
||||
#endif
|
||||
|
||||
if (buffers & PIPE_CLEAR_COLOR) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_pstipple.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
#include "sp_clear.h"
|
||||
|
|
@ -88,6 +89,14 @@ softpipe_destroy( struct pipe_context *pipe )
|
|||
struct softpipe_context *softpipe = softpipe_context( pipe );
|
||||
uint i;
|
||||
|
||||
#if DO_PSTIPPLE_IN_HELPER_MODULE
|
||||
if (softpipe->pstipple.sampler)
|
||||
pipe->delete_sampler_state(pipe, softpipe->pstipple.sampler);
|
||||
|
||||
pipe_resource_reference(&softpipe->pstipple.texture, NULL);
|
||||
pipe_sampler_view_reference(&softpipe->pstipple.sampler_view, NULL);
|
||||
#endif
|
||||
|
||||
if (softpipe->draw)
|
||||
draw_destroy( softpipe->draw );
|
||||
|
||||
|
|
@ -341,6 +350,11 @@ softpipe_create_context( struct pipe_screen *screen,
|
|||
|
||||
sp_init_surface_functions(softpipe);
|
||||
|
||||
#if DO_PSTIPPLE_IN_HELPER_MODULE
|
||||
/* create the polgon stipple sampler */
|
||||
softpipe->pstipple.sampler = util_pstipple_create_sampler(&softpipe->pipe);
|
||||
#endif
|
||||
|
||||
return &softpipe->pipe;
|
||||
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -38,8 +38,11 @@
|
|||
#include "sp_quad_pipe.h"
|
||||
|
||||
|
||||
/** Do polygon stipple in the driver here, or in the draw module? */
|
||||
#define DO_PSTIPPLE_IN_DRAW_MODULE 1
|
||||
/** Do polygon stipple in the draw module? */
|
||||
#define DO_PSTIPPLE_IN_DRAW_MODULE 0
|
||||
|
||||
/** Do polygon stipple with the util module? */
|
||||
#define DO_PSTIPPLE_IN_HELPER_MODULE 1
|
||||
|
||||
|
||||
struct softpipe_vbuf_render;
|
||||
|
|
@ -144,6 +147,13 @@ struct softpipe_context {
|
|||
struct pipe_query *render_cond_query;
|
||||
uint render_cond_mode;
|
||||
|
||||
/** Polygon stipple items */
|
||||
struct {
|
||||
struct pipe_resource *texture;
|
||||
struct pipe_sampler_state *sampler;
|
||||
struct pipe_sampler_view *sampler_view;
|
||||
} pstipple;
|
||||
|
||||
/** Software quad rendering pipeline */
|
||||
struct {
|
||||
struct quad_stage *shade;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode)
|
|||
sp->reduced_api_prim = u_reduced_prim(mode);
|
||||
|
||||
if (sp->dirty) {
|
||||
softpipe_update_derived(sp);
|
||||
softpipe_update_derived(sp, sp->reduced_api_prim);
|
||||
}
|
||||
|
||||
softpipe_map_transfers(sp);
|
||||
|
|
@ -122,7 +122,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
|
|||
sp->reduced_api_prim = u_reduced_prim(info->mode);
|
||||
|
||||
if (sp->dirty) {
|
||||
softpipe_update_derived(sp);
|
||||
softpipe_update_derived(sp, sp->reduced_api_prim);
|
||||
}
|
||||
|
||||
softpipe_map_transfers(sp);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
|
|||
insert_stage_at_head( sp, sp->quad.shade );
|
||||
}
|
||||
|
||||
#if !DO_PSTIPPLE_IN_DRAW_MODULE
|
||||
#if !DO_PSTIPPLE_IN_DRAW_MODULE && !DO_PSTIPPLE_IN_HELPER_MODULE
|
||||
if (sp->rasterizer->poly_stipple_enable)
|
||||
insert_stage_at_head( sp, sp->quad.pstipple );
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1397,7 +1397,7 @@ sp_setup_prepare(struct setup_context *setup)
|
|||
struct softpipe_context *sp = setup->softpipe;
|
||||
|
||||
if (sp->dirty) {
|
||||
softpipe_update_derived(sp);
|
||||
softpipe_update_derived(sp, sp->reduced_api_prim);
|
||||
}
|
||||
|
||||
/* Note: nr_attrs is only used for debugging (vertex printing) */
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ struct vertex_info;
|
|||
|
||||
struct sp_fragment_shader_variant_key
|
||||
{
|
||||
int foo; /* XXX temporary */
|
||||
boolean polygon_stipple;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -72,6 +72,8 @@ struct sp_fragment_shader_variant
|
|||
struct sp_fragment_shader_variant_key key;
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
unsigned stipple_sampler_unit;
|
||||
|
||||
/* See comments about this elsewhere */
|
||||
#if 0
|
||||
struct draw_fragment_shader *draw_shader;
|
||||
|
|
@ -150,7 +152,7 @@ softpipe_set_framebuffer_state(struct pipe_context *,
|
|||
const struct pipe_framebuffer_state *);
|
||||
|
||||
void
|
||||
softpipe_update_derived(struct softpipe_context *softpipe);
|
||||
softpipe_update_derived(struct softpipe_context *softpipe, unsigned prim);
|
||||
|
||||
void
|
||||
softpipe_draw_vbo(struct pipe_context *pipe,
|
||||
|
|
@ -179,6 +181,12 @@ struct vertex_info *
|
|||
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
|
||||
|
||||
|
||||
struct sp_fragment_shader_variant *
|
||||
softpipe_find_fs_variant(struct softpipe_context *softpipe,
|
||||
struct sp_fragment_shader *fs,
|
||||
const struct sp_fragment_shader_variant_key *key);
|
||||
|
||||
|
||||
struct sp_fragment_shader_variant *
|
||||
softpipe_find_fs_variant(struct softpipe_context *softpipe,
|
||||
struct sp_fragment_shader *fs,
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#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"
|
||||
|
|
@ -242,12 +244,15 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
|
|||
|
||||
|
||||
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);
|
||||
|
|
@ -276,11 +281,63 @@ update_fragment_shader(struct softpipe_context *softpipe)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
|
|
@ -290,10 +347,23 @@ softpipe_update_derived(struct softpipe_context *softpipe)
|
|||
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 |
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_pstipple.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_vs.h"
|
||||
#include "draw/draw_gs.h"
|
||||
|
|
@ -51,7 +52,15 @@ create_fs_variant(struct softpipe_context *softpipe,
|
|||
const struct sp_fragment_shader_variant_key *key)
|
||||
{
|
||||
struct sp_fragment_shader_variant *var;
|
||||
struct pipe_shader_state *curfs = &fs->shader;
|
||||
struct pipe_shader_state *stipple_fs = NULL, *curfs = &fs->shader;
|
||||
unsigned unit = 0;
|
||||
|
||||
if (key->polygon_stipple) {
|
||||
/* get new shader that implements polygon stippling */
|
||||
stipple_fs = util_pstipple_create_fragment_shader(&softpipe->pipe,
|
||||
curfs, &unit);
|
||||
curfs = stipple_fs;
|
||||
}
|
||||
|
||||
/* codegen, create variant object */
|
||||
var = softpipe_create_fs_variant_sse(softpipe, curfs);
|
||||
|
|
@ -62,6 +71,7 @@ create_fs_variant(struct softpipe_context *softpipe,
|
|||
if (var) {
|
||||
var->key = *key;
|
||||
var->tokens = tgsi_dup_tokens(curfs->tokens);
|
||||
var->stipple_sampler_unit = unit;
|
||||
|
||||
tgsi_scan_shader(var->tokens, &var->info);
|
||||
|
||||
|
|
@ -82,6 +92,11 @@ create_fs_variant(struct softpipe_context *softpipe,
|
|||
fs->variants = var;
|
||||
}
|
||||
|
||||
if (stipple_fs) {
|
||||
free((void *) stipple_fs->tokens);
|
||||
free(stipple_fs);
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue