From 53bd9796a1395e4acde884ff55cb7ee18586595a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 11 Jun 2010 13:31:52 -0400 Subject: [PATCH] gallium/softpipe/draw: support samplers in geometry shaders --- src/gallium/auxiliary/draw/draw_context.c | 13 +++- src/gallium/auxiliary/draw/draw_context.h | 1 + src/gallium/drivers/softpipe/sp_context.c | 24 +++++- src/gallium/drivers/softpipe/sp_context.h | 6 ++ src/gallium/drivers/softpipe/sp_flush.c | 3 + src/gallium/drivers/softpipe/sp_state.h | 10 +++ .../drivers/softpipe/sp_state_derived.c | 13 ++++ src/gallium/drivers/softpipe/sp_state_fs.c | 3 + .../drivers/softpipe/sp_state_sampler.c | 77 +++++++++++++++++++ src/gallium/include/pipe/p_context.h | 7 ++ src/gallium/include/pipe/p_state.h | 1 + 11 files changed, 153 insertions(+), 5 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 7c7702549e0..dab95e50515 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -435,13 +435,18 @@ draw_num_shader_outputs(const struct draw_context *draw) */ void draw_texture_samplers(struct draw_context *draw, + uint shader, uint num_samplers, struct tgsi_sampler **samplers) { - draw->vs.num_samplers = num_samplers; - draw->vs.samplers = samplers; - draw->gs.num_samplers = num_samplers; - draw->gs.samplers = samplers; + if (shader == PIPE_SHADER_VERTEX) { + draw->vs.num_samplers = num_samplers; + draw->vs.samplers = samplers; + } else { + debug_assert(shader == PIPE_SHADER_GEOMETRY); + draw->gs.num_samplers = num_samplers; + draw->gs.samplers = samplers; + } } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 103d6538b81..c0122f2aca5 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -97,6 +97,7 @@ draw_num_shader_outputs(const struct draw_context *draw); void draw_texture_samplers(struct draw_context *draw, + uint shader_type, uint num_samplers, struct tgsi_sampler **samplers); diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 401a28ad312..12ef98aac75 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -114,6 +114,11 @@ softpipe_destroy( struct pipe_context *pipe ) pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL); } + for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { + sp_destroy_tex_tile_cache(softpipe->geometry_tex_cache[i]); + pipe_sampler_view_reference(&softpipe->geometry_sampler_views[i], NULL); + } + for (i = 0; i < PIPE_SHADER_TYPES; i++) { uint j; @@ -174,7 +179,12 @@ softpipe_is_resource_referenced( struct pipe_context *pipe, softpipe->vertex_tex_cache[i]->texture == texture) return PIPE_REFERENCED_FOR_READ; } - + for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { + if (softpipe->geometry_tex_cache[i] && + softpipe->geometry_tex_cache[i]->texture == texture) + return PIPE_REFERENCED_FOR_READ; + } + return PIPE_UNREFERENCED; } @@ -225,6 +235,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; softpipe->pipe.bind_fragment_sampler_states = softpipe_bind_sampler_states; softpipe->pipe.bind_vertex_sampler_states = softpipe_bind_vertex_sampler_states; + softpipe->pipe.bind_geometry_sampler_states = softpipe_bind_geometry_sampler_states; softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; @@ -265,6 +276,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views; softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_sampler_views; + softpipe->pipe.set_geometry_sampler_views = softpipe_set_geometry_sampler_views; softpipe->pipe.create_sampler_view = softpipe_create_sampler_view; softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy; softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; @@ -301,6 +313,9 @@ softpipe_create_context( struct pipe_screen *screen, for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); } + for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { + softpipe->geometry_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); + } softpipe->fs_machine = tgsi_exec_machine_create(); @@ -319,10 +334,17 @@ softpipe_create_context( struct pipe_screen *screen, goto fail; draw_texture_samplers(softpipe->draw, + PIPE_SHADER_VERTEX, PIPE_MAX_VERTEX_SAMPLERS, (struct tgsi_sampler **) softpipe->tgsi.vert_samplers_list); + draw_texture_samplers(softpipe->draw, + PIPE_SHADER_GEOMETRY, + PIPE_MAX_GEOMETRY_SAMPLERS, + (struct tgsi_sampler **) + softpipe->tgsi.geom_samplers_list); + if (debug_get_bool_option( "SP_NO_RAST", FALSE )) softpipe->no_rast = TRUE; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index e641a81d1fb..53115a827d0 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -60,6 +60,7 @@ struct softpipe_context { struct pipe_blend_state *blend; struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_state *geometry_samplers[PIPE_MAX_GEOMETRY_SAMPLERS]; struct pipe_depth_stencil_alpha_state *depth_stencil; struct pipe_rasterizer_state *rasterizer; struct sp_fragment_shader *fs; @@ -78,6 +79,7 @@ struct softpipe_context { struct pipe_scissor_state scissor; struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct { @@ -92,6 +94,8 @@ struct softpipe_context { unsigned num_sampler_views; unsigned num_vertex_samplers; unsigned num_vertex_sampler_views; + unsigned num_geometry_samplers; + unsigned num_geometry_sampler_views; unsigned num_vertex_buffers; unsigned dirty; /**< Mask of SP_NEW_x flags */ @@ -148,6 +152,7 @@ struct softpipe_context { /** TGSI exec things */ struct { + struct sp_sampler_varient *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS]; struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS]; struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS]; } tgsi; @@ -169,6 +174,7 @@ struct softpipe_context { unsigned tex_timestamp; struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; struct softpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS]; + struct softpipe_tex_tile_cache *geometry_tex_cache[PIPE_MAX_GEOMETRY_SAMPLERS]; unsigned use_sse : 1; unsigned dump_fs : 1; diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 5024fc8a819..4a53ef048f3 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -56,6 +56,9 @@ softpipe_flush( struct pipe_context *pipe, for (i = 0; i < softpipe->num_vertex_sampler_views; i++) { sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]); } + for (i = 0; i < softpipe->num_geometry_sampler_views; i++) { + sp_flush_tex_tile_cache(softpipe->geometry_tex_cache[i]); + } } if (flags & PIPE_FLUSH_SWAPBUFFERS) { diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index d0b73cc850c..7d6b86dce04 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -100,6 +100,7 @@ struct sp_vertex_shader { struct sp_geometry_shader { struct pipe_shader_state shader; struct draw_geometry_shader *draw_data; + int max_sampler; }; struct sp_velems_state { @@ -128,6 +129,10 @@ void softpipe_bind_vertex_sampler_states(struct pipe_context *, unsigned num_samplers, void **samplers); +void +softpipe_bind_geometry_sampler_states(struct pipe_context *, + unsigned num_samplers, + void **samplers); void softpipe_delete_sampler_state(struct pipe_context *, void *); void * @@ -195,6 +200,11 @@ softpipe_set_vertex_sampler_views(struct pipe_context *, unsigned num, struct pipe_sampler_view **); +void +softpipe_set_geometry_sampler_views(struct pipe_context *, + unsigned num, + struct pipe_sampler_view **); + struct pipe_sampler_view * softpipe_create_sampler_view(struct pipe_context *pipe, struct pipe_resource *texture, diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 4c6d4909f5b..3ba4d934fd2 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -225,6 +225,19 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) } } } + + for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { + struct softpipe_tex_tile_cache *tc = softpipe->geometry_tex_cache[i]; + + if (tc->texture) { + struct softpipe_resource *spt = softpipe_resource(tc->texture); + + if (spt->timestamp != tc->timestamp) { + sp_tex_tile_cache_validate_texture(tc); + tc->timestamp = spt->timestamp; + } + } + } } diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 2fff80c4385..3fbf1f25781 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -35,6 +35,7 @@ #include "util/u_inlines.h" #include "draw/draw_context.h" #include "draw/draw_vs.h" +#include "draw/draw_gs.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_scan.h" @@ -223,6 +224,8 @@ softpipe_create_gs_state(struct pipe_context *pipe, if (state->draw_data == NULL) goto fail; + state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER]; + return state; fail: diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 2692f06c927..09b0ffc1dad 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -121,6 +121,33 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe, softpipe->dirty |= SP_NEW_SAMPLER; } +void +softpipe_bind_geometry_sampler_states(struct pipe_context *pipe, + unsigned num_samplers, + void **samplers) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned i; + + assert(num_samplers <= PIPE_MAX_GEOMETRY_SAMPLERS); + + /* Check for no-op */ + if (num_samplers == softpipe->num_geometry_samplers && + !memcmp(softpipe->geometry_samplers, samplers, num_samplers * sizeof(void *))) + return; + + draw_flush(softpipe->draw); + + for (i = 0; i < num_samplers; ++i) + softpipe->geometry_samplers[i] = samplers[i]; + for (i = num_samplers; i < PIPE_MAX_GEOMETRY_SAMPLERS; ++i) + softpipe->geometry_samplers[i] = NULL; + + softpipe->num_geometry_samplers = num_samplers; + + softpipe->dirty |= SP_NEW_SAMPLER; +} + struct pipe_sampler_view * softpipe_create_sampler_view(struct pipe_context *pipe, @@ -210,6 +237,36 @@ softpipe_set_vertex_sampler_views(struct pipe_context *pipe, softpipe->dirty |= SP_NEW_TEXTURE; } +void +softpipe_set_geometry_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint i; + + assert(num <= PIPE_MAX_GEOMETRY_SAMPLERS); + + /* Check for no-op */ + if (num == softpipe->num_geometry_sampler_views && + !memcmp(softpipe->geometry_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { + return; + } + + draw_flush(softpipe->draw); + + for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { + struct pipe_sampler_view *view = i < num ? views[i] : NULL; + + pipe_sampler_view_reference(&softpipe->geometry_sampler_views[i], view); + sp_tex_tile_cache_set_sampler_view(softpipe->geometry_tex_cache[i], view); + } + + softpipe->num_geometry_sampler_views = num; + + softpipe->dirty |= SP_NEW_TEXTURE; +} + /** * Find/create an sp_sampler_varient object for sampling the given texture, @@ -293,6 +350,26 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) } } + for (i = 0; i <= softpipe->gs->max_sampler; i++) { + if (softpipe->geometry_samplers[i]) { + struct pipe_resource *texture = NULL; + + if (softpipe->geometry_sampler_views[i]) { + texture = softpipe->geometry_sampler_views[i]->texture; + } + + softpipe->tgsi.geom_samplers_list[i] = + get_sampler_varient( i, + sp_sampler(softpipe->geometry_samplers[i]), + texture, + TGSI_PROCESSOR_GEOMETRY ); + + sp_sampler_varient_bind_texture( softpipe->tgsi.geom_samplers_list[i], + softpipe->geometry_tex_cache[i], + texture ); + } + } + for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { if (softpipe->sampler[i]) { struct pipe_resource *texture = NULL; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 72afad60ba9..7ec3d63a3fd 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -158,6 +158,9 @@ struct pipe_context { void (*bind_vertex_sampler_states)(struct pipe_context *, unsigned num_samplers, void **samplers); + void (*bind_geometry_sampler_states)(struct pipe_context *, + unsigned num_samplers, + void **samplers); void (*delete_sampler_state)(struct pipe_context *, void *); void * (*create_rasterizer_state)(struct pipe_context *, @@ -238,6 +241,10 @@ struct pipe_context { unsigned num_views, struct pipe_sampler_view **); + void (*set_geometry_sampler_views)(struct pipe_context *, + unsigned num_views, + struct pipe_sampler_view **); + void (*set_vertex_buffers)( struct pipe_context *, unsigned num_buffers, const struct pipe_vertex_buffer * ); diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 5ed1cca67a5..6231f06ec71 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -60,6 +60,7 @@ extern "C" { #define PIPE_MAX_CONSTANT_BUFFERS 32 #define PIPE_MAX_SAMPLERS 16 #define PIPE_MAX_VERTEX_SAMPLERS 16 +#define PIPE_MAX_GEOMETRY_SAMPLERS 16 #define PIPE_MAX_SHADER_INPUTS 16 #define PIPE_MAX_SHADER_OUTPUTS 16 #define PIPE_MAX_TEXTURE_LEVELS 16 -- 2.30.2