From d6c3e6d8f34fc39dcbe9395c3a5953af726443f1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 4 Aug 2012 08:46:41 -0600 Subject: [PATCH] softpipe: consolidate sampler-related arrays MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Combine separate arrays for vertex/fragment/geometry samplers, etc into one array indexed by PIPE_SHADER_x. This allows us to collapse separate code for vertex/fragment/geometry state into loops over the shader stage. More to come. Reviewed-by: José Fonseca --- src/gallium/drivers/softpipe/sp_context.c | 23 +--- src/gallium/drivers/softpipe/sp_context.h | 22 ++-- src/gallium/drivers/softpipe/sp_flush.c | 14 +-- src/gallium/drivers/softpipe/sp_quad_fs.c | 2 +- src/gallium/drivers/softpipe/sp_state_derived.c | 6 +- src/gallium/drivers/softpipe/sp_state_sampler.c | 153 ++++++++++++------------ 6 files changed, 99 insertions(+), 121 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 3d8a69a..e2e32b9 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -122,21 +122,6 @@ softpipe_destroy( struct pipe_context *pipe ) sp_destroy_tile_cache(softpipe->zsbuf_cache); pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - sp_destroy_tex_tile_cache(softpipe->tex_cache[PIPE_SHADER_FRAGMENT][i]); - pipe_sampler_view_reference(&softpipe->fragment_sampler_views[i], NULL); - } - - for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - sp_destroy_tex_tile_cache(softpipe->tex_cache[PIPE_SHADER_VERTEX][i]); - 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->tex_cache[PIPE_SHADER_GEOMETRY][i]); - pipe_sampler_view_reference(&softpipe->geometry_sampler_views[i], NULL); - } - for (sh = 0; sh < Elements(softpipe->tex_cache); sh++) { for (i = 0; i < Elements(softpipe->tex_cache[0]); i++) { sp_destroy_tex_tile_cache(softpipe->tex_cache[sh][i]); @@ -231,6 +216,10 @@ softpipe_create_context( struct pipe_screen *screen, struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); uint i, sh; + /* Check since we have arrays[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS] */ + STATIC_ASSERT(PIPE_MAX_SAMPLERS == PIPE_MAX_VERTEX_SAMPLERS); + STATIC_ASSERT(PIPE_MAX_SAMPLERS == PIPE_MAX_GEOMETRY_SAMPLERS); + util_init_math(); softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE ); @@ -303,13 +292,13 @@ softpipe_create_context( struct pipe_screen *screen, PIPE_SHADER_VERTEX, PIPE_MAX_VERTEX_SAMPLERS, (struct tgsi_sampler **) - softpipe->tgsi.vert_samplers_list); + softpipe->tgsi.samplers_list[PIPE_SHADER_VERTEX]); draw_texture_samplers(softpipe->draw, PIPE_SHADER_GEOMETRY, PIPE_MAX_GEOMETRY_SAMPLERS, (struct tgsi_sampler **) - softpipe->tgsi.geom_samplers_list); + softpipe->tgsi.samplers_list[PIPE_SHADER_GEOMETRY]); if (debug_get_bool_option( "SOFTPIPE_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 95f5b76..2185fb8 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -60,9 +60,7 @@ struct softpipe_context { /** Constant state objects */ struct pipe_blend_state *blend; - struct pipe_sampler_state *fragment_samplers[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_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; struct pipe_depth_stencil_alpha_state *depth_stencil; struct pipe_rasterizer_state *rasterizer; struct sp_fragment_shader *fs; @@ -81,9 +79,8 @@ struct softpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_sampler_view *fragment_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_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_GEOMETRY_SAMPLERS]; + struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_index_buffer index_buffer; @@ -94,12 +91,9 @@ struct softpipe_context { struct pipe_query_data_so_statistics so_stats; unsigned num_primitives_generated; - unsigned num_fragment_samplers; - unsigned num_fragment_sampler_views; - unsigned num_vertex_samplers; - unsigned num_vertex_sampler_views; - unsigned num_geometry_samplers; - unsigned num_geometry_sampler_views; + unsigned num_samplers[PIPE_SHADER_TYPES]; + unsigned num_sampler_views[PIPE_SHADER_TYPES]; + unsigned num_vertex_buffers; unsigned dirty; /**< Mask of SP_NEW_x flags */ @@ -164,9 +158,7 @@ struct softpipe_context { /** TGSI exec things */ struct { - struct sp_sampler_variant *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS]; - struct sp_sampler_variant *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS]; - struct sp_sampler_variant *frag_samplers_list[PIPE_MAX_SAMPLERS]; + struct sp_sampler_variant *samplers_list[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; } tgsi; struct tgsi_exec_machine *fs_machine; diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 4651e8b..9b8d492 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -52,14 +52,12 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); if (flags & SP_FLUSH_TEXTURE_CACHE) { - for (i = 0; i < softpipe->num_fragment_sampler_views; i++) { - sp_flush_tex_tile_cache(softpipe->tex_cache[PIPE_SHADER_FRAGMENT][i]); - } - for (i = 0; i < softpipe->num_vertex_sampler_views; i++) { - sp_flush_tex_tile_cache(softpipe->tex_cache[PIPE_SHADER_VERTEX][i]); - } - for (i = 0; i < softpipe->num_geometry_sampler_views; i++) { - sp_flush_tex_tile_cache(softpipe->tex_cache[PIPE_SHADER_GEOMETRY][i]); + unsigned sh; + + for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { + for (i = 0; i < softpipe->num_sampler_views[sh]; i++) { + sp_flush_tex_tile_cache(softpipe->tex_cache[sh][i]); + } } } diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 8ec1aa2..892d9c6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -153,7 +153,7 @@ shade_begin(struct quad_stage *qs) softpipe->fs_variant->prepare( softpipe->fs_variant, softpipe->fs_machine, (struct tgsi_sampler **) - softpipe->tgsi.frag_samplers_list ); + softpipe->tgsi.samplers_list[PIPE_SHADER_FRAGMENT] ); qs->next->begin(qs->next); } diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 7fbff73..f88a7fd 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -305,13 +305,13 @@ update_polygon_stipple_enable(struct softpipe_context *softpipe, unsigned prim) softpipe->fs_variant->key.polygon_stipple) { const unsigned unit = softpipe->fs_variant->stipple_sampler_unit; - assert(unit >= softpipe->num_fragment_samplers); + assert(unit >= softpipe->num_samplers[PIPE_SHADER_FRAGMENT]); /* sampler state */ - softpipe->fragment_samplers[unit] = softpipe->pstipple.sampler; + softpipe->samplers[PIPE_SHADER_FRAGMENT][unit] = softpipe->pstipple.sampler; /* sampler view */ - pipe_sampler_view_reference(&softpipe->fragment_sampler_views[unit], + pipe_sampler_view_reference(&softpipe->sampler_views[PIPE_SHADER_FRAGMENT][unit], softpipe->pstipple.sampler_view); sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[PIPE_SHADER_FRAGMENT][unit], diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 260295d..70b9c60 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -76,18 +76,18 @@ softpipe_bind_fragment_sampler_states(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == softpipe->num_fragment_samplers && - !memcmp(softpipe->fragment_samplers, sampler, num * sizeof(void *))) + if (num == softpipe->num_samplers[PIPE_SHADER_FRAGMENT] && + !memcmp(softpipe->samplers[PIPE_SHADER_FRAGMENT], sampler, num * sizeof(void *))) return; draw_flush(softpipe->draw); for (i = 0; i < num; ++i) - softpipe->fragment_samplers[i] = sampler[i]; + softpipe->samplers[PIPE_SHADER_FRAGMENT][i] = sampler[i]; for (i = num; i < PIPE_MAX_SAMPLERS; ++i) - softpipe->fragment_samplers[i] = NULL; + softpipe->samplers[PIPE_SHADER_FRAGMENT][i] = NULL; - softpipe->num_fragment_samplers = num; + softpipe->num_samplers[PIPE_SHADER_FRAGMENT] = num; softpipe->dirty |= SP_NEW_SAMPLER; } @@ -104,22 +104,22 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe, assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ - if (num_samplers == softpipe->num_vertex_samplers && - !memcmp(softpipe->vertex_samplers, samplers, num_samplers * sizeof(void *))) + if (num_samplers == softpipe->num_samplers[PIPE_SHADER_VERTEX] && + !memcmp(softpipe->samplers[PIPE_SHADER_VERTEX], samplers, num_samplers * sizeof(void *))) return; draw_flush(softpipe->draw); for (i = 0; i < num_samplers; ++i) - softpipe->vertex_samplers[i] = samplers[i]; + softpipe->samplers[PIPE_SHADER_VERTEX][i] = samplers[i]; for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) - softpipe->vertex_samplers[i] = NULL; + softpipe->samplers[PIPE_SHADER_VERTEX][i] = NULL; - softpipe->num_vertex_samplers = num_samplers; + softpipe->num_samplers[PIPE_SHADER_VERTEX] = num_samplers; draw_set_samplers(softpipe->draw, - softpipe->vertex_samplers, - softpipe->num_vertex_samplers); + softpipe->samplers[PIPE_SHADER_VERTEX], + softpipe->num_samplers[PIPE_SHADER_VERTEX]); softpipe->dirty |= SP_NEW_SAMPLER; } @@ -135,18 +135,18 @@ softpipe_bind_geometry_sampler_states(struct pipe_context *pipe, 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 *))) + if (num_samplers == softpipe->num_samplers[PIPE_SHADER_GEOMETRY] && + !memcmp(softpipe->samplers[PIPE_SHADER_GEOMETRY], 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->samplers[PIPE_SHADER_GEOMETRY][i] = samplers[i]; + for (i = num_samplers; i < PIPE_MAX_SAMPLERS; ++i) + softpipe->samplers[PIPE_SHADER_GEOMETRY][i] = NULL; - softpipe->num_geometry_samplers = num_samplers; + softpipe->num_samplers[PIPE_SHADER_GEOMETRY] = num_samplers; softpipe->dirty |= SP_NEW_SAMPLER; } @@ -191,8 +191,8 @@ softpipe_set_fragment_sampler_views(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == softpipe->num_fragment_sampler_views && - !memcmp(softpipe->fragment_sampler_views, views, + if (num == softpipe->num_sampler_views[PIPE_SHADER_FRAGMENT] && + !memcmp(softpipe->sampler_views[PIPE_SHADER_FRAGMENT], views, num * sizeof(struct pipe_sampler_view *))) return; @@ -201,11 +201,11 @@ softpipe_set_fragment_sampler_views(struct pipe_context *pipe, for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; - pipe_sampler_view_reference(&softpipe->fragment_sampler_views[i], view); + pipe_sampler_view_reference(&softpipe->sampler_views[PIPE_SHADER_FRAGMENT][i], view); sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[PIPE_SHADER_FRAGMENT][i], view); } - softpipe->num_fragment_sampler_views = num; + softpipe->num_sampler_views[PIPE_SHADER_FRAGMENT] = num; softpipe->dirty |= SP_NEW_TEXTURE; } @@ -222,8 +222,9 @@ softpipe_set_vertex_sampler_views(struct pipe_context *pipe, assert(num <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ - if (num == softpipe->num_vertex_sampler_views && - !memcmp(softpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { + if (num == softpipe->num_sampler_views[PIPE_SHADER_VERTEX] && + !memcmp(softpipe->sampler_views[PIPE_SHADER_VERTEX], + views, num * sizeof(struct pipe_sampler_view *))) { return; } @@ -232,15 +233,15 @@ softpipe_set_vertex_sampler_views(struct pipe_context *pipe, for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; - pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], view); + pipe_sampler_view_reference(&softpipe->sampler_views[PIPE_SHADER_VERTEX][i], view); sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[PIPE_SHADER_VERTEX][i], view); } - softpipe->num_vertex_sampler_views = num; + softpipe->num_sampler_views[PIPE_SHADER_VERTEX] = num; draw_set_sampler_views(softpipe->draw, - softpipe->vertex_sampler_views, - softpipe->num_vertex_sampler_views); + softpipe->sampler_views[PIPE_SHADER_VERTEX], + softpipe->num_sampler_views[PIPE_SHADER_VERTEX]); softpipe->dirty |= SP_NEW_TEXTURE; } @@ -257,8 +258,8 @@ softpipe_set_geometry_sampler_views(struct pipe_context *pipe, 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 *))) { + if (num == softpipe->num_sampler_views[PIPE_SHADER_GEOMETRY] && + !memcmp(softpipe->sampler_views[PIPE_SHADER_GEOMETRY], views, num * sizeof(struct pipe_sampler_view *))) { return; } @@ -267,11 +268,11 @@ softpipe_set_geometry_sampler_views(struct pipe_context *pipe, 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); + pipe_sampler_view_reference(&softpipe->sampler_views[PIPE_SHADER_GEOMETRY][i], view); sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[PIPE_SHADER_GEOMETRY][i], view); } - softpipe->num_geometry_sampler_views = num; + softpipe->num_sampler_views[PIPE_SHADER_GEOMETRY] = num; softpipe->dirty |= SP_NEW_TEXTURE; } @@ -332,63 +333,61 @@ get_sampler_variant( unsigned unit, } -void -softpipe_reset_sampler_variants(struct softpipe_context *softpipe) +/** + * Reset the sampler variants for a shader stage (vert, frag, geom). + */ +static void +reset_sampler_variants(struct softpipe_context *softpipe, + unsigned shader, + unsigned tgsi_shader, + int max_sampler) { int i; + for (i = 0; i <= max_sampler; i++) { + if (softpipe->samplers[shader][i]) { + softpipe->tgsi.samplers_list[shader][i] = + get_sampler_variant(i, + sp_sampler(softpipe->samplers[shader][i]), + softpipe->sampler_views[shader][i], + tgsi_shader); + + sp_sampler_variant_bind_view(softpipe->tgsi.samplers_list[shader][i], + softpipe->tex_cache[shader][i], + softpipe->sampler_views[shader][i]); + } + } +} + + +void +softpipe_reset_sampler_variants(struct softpipe_context *softpipe) +{ /* It's a bit hard to build these samplers ahead of time -- don't * really know which samplers are going to be used for vertex and * fragment programs. */ - for (i = 0; i <= softpipe->vs->max_sampler; i++) { - if (softpipe->vertex_samplers[i]) { - softpipe->tgsi.vert_samplers_list[i] = - get_sampler_variant( i, - sp_sampler(softpipe->vertex_samplers[i]), - softpipe->vertex_sampler_views[i], - TGSI_PROCESSOR_VERTEX ); - - sp_sampler_variant_bind_view( softpipe->tgsi.vert_samplers_list[i], - softpipe->tex_cache[PIPE_SHADER_VERTEX][i], - softpipe->vertex_sampler_views[i] ); - } - } - if (softpipe->gs) { - for (i = 0; i <= softpipe->gs->max_sampler; i++) { - if (softpipe->geometry_samplers[i]) { - softpipe->tgsi.geom_samplers_list[i] = - get_sampler_variant( - i, - sp_sampler(softpipe->geometry_samplers[i]), - softpipe->geometry_sampler_views[i], - TGSI_PROCESSOR_GEOMETRY ); - - sp_sampler_variant_bind_view( - softpipe->tgsi.geom_samplers_list[i], - softpipe->tex_cache[PIPE_SHADER_GEOMETRY][i], - softpipe->geometry_sampler_views[i] ); - } - } - } + /* XXX note: PIPE_SHADER_x != TGSI_PROCESSOR_x (fix that someday) */ + reset_sampler_variants(softpipe, + PIPE_SHADER_VERTEX, + TGSI_PROCESSOR_VERTEX, + softpipe->vs->max_sampler); - for (i = 0; i <= softpipe->fs_variant->info.file_max[TGSI_FILE_SAMPLER]; i++) { - if (softpipe->fragment_samplers[i]) { - assert(softpipe->fragment_sampler_views[i]->texture); - softpipe->tgsi.frag_samplers_list[i] = - get_sampler_variant( i, - sp_sampler(softpipe->fragment_samplers[i]), - softpipe->fragment_sampler_views[i], - TGSI_PROCESSOR_FRAGMENT ); - - sp_sampler_variant_bind_view( softpipe->tgsi.frag_samplers_list[i], - softpipe->tex_cache[PIPE_SHADER_FRAGMENT][i], - softpipe->fragment_sampler_views[i] ); - } + reset_sampler_variants(softpipe, + PIPE_SHADER_FRAGMENT, + TGSI_PROCESSOR_FRAGMENT, + softpipe->fs_variant->info.file_max[TGSI_FILE_SAMPLER]); + + if (softpipe->gs) { + reset_sampler_variants(softpipe, + PIPE_SHADER_GEOMETRY, + TGSI_PROCESSOR_GEOMETRY, + softpipe->gs->max_sampler); } } + static void softpipe_delete_sampler_state(struct pipe_context *pipe, void *sampler) -- 2.7.4