From: Jakob Bornecrantz Date: Sat, 5 Mar 2011 12:27:00 +0000 (+0100) Subject: gallium: Delay the creation of simple helper shaders X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1a79064da12a8be71dca7656e5eebc4b85d2b35f;p=mesa.git gallium: Delay the creation of simple helper shaders --- diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index d1d7e86fbba..421726b40e0 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -128,21 +128,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } - /* vertex shader - still required to provide the linkage between - * fragment shader input semantics and vertex_element/buffers. - */ - { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC }; - const uint semantic_indexes[] = { 0, 0 }; - ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes); - } - - /* fragment shader */ - ctx->fs[TGSI_WRITEMASK_XYZW] = - util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR); ctx->vbuf = NULL; /* init vertex data that doesn't change */ @@ -170,7 +155,8 @@ util_destroy_blit(struct blit_state *ctx) struct pipe_context *pipe = ctx->pipe; unsigned i; - pipe->delete_vs_state(pipe, ctx->vs); + if (ctx->vs) + pipe->delete_vs_state(pipe, ctx->vs); for (i = 0; i < Elements(ctx->fs); i++) if (ctx->fs[i]) @@ -185,6 +171,59 @@ util_destroy_blit(struct blit_state *ctx) } +/** + * Helper function to set the fragment shaders. + */ +static INLINE void +set_fragment_shader(struct blit_state *ctx, uint writemask) +{ + if (!ctx->fs[writemask]) + ctx->fs[writemask] = + util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D, + TGSI_INTERPOLATE_LINEAR, + writemask); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]); +} + + +/** + * Helper function to set the depthwrite shader. + */ +static INLINE void +set_depth_fragment_shader(struct blit_state *ctx) +{ + if (!ctx->fs_depth) + ctx->fs_depth = + util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D, + TGSI_INTERPOLATE_LINEAR); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth); +} + + +/** + * Helper function to set the vertex shader. + */ +static INLINE void +set_vertex_shader(struct blit_state *ctx) +{ + /* vertex shader - still required to provide the linkage between + * fragment shader input semantics and vertex_element/buffers. + */ + if (!ctx->vs) { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, + semantic_names, + semantic_indexes); + } + + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); +} + + /** * Get offset of next free slot in vertex buffer for quad vertices. */ @@ -530,22 +569,11 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* shaders */ if (dst_is_depth) { - if (ctx->fs_depth == NULL) - ctx->fs_depth = - util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR); - - cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth); + set_depth_fragment_shader(ctx); } else { - if (ctx->fs[writemask] == NULL) - ctx->fs[writemask] = - util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR, - writemask); - - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]); + set_fragment_shader(ctx, writemask); } - cso_set_vertex_shader_handle(ctx->cso, ctx->vs); + set_vertex_shader(ctx); /* drawing dest */ memset(&fb, 0, sizeof(fb)); @@ -720,8 +748,8 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view); /* shaders */ - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]); - cso_set_vertex_shader_handle(ctx->cso, ctx->vs); + set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW); + set_vertex_shader(ctx); /* drawing dest */ memset(&fb, 0, sizeof(fb)); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 5bf0f53d084..4a1662462e5 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -67,7 +67,7 @@ struct gen_mipmap_state struct pipe_vertex_element velem[2]; void *vs; - void *fs1d, *fs2d, *fs3d, *fsCube, *fs1da, *fs2da; + void *fs[TGSI_TEXTURE_COUNT]; /**< Not all are used, but simplifies code */ struct pipe_resource *vbuf; /**< quad vertices */ unsigned vbuf_slot; @@ -1301,34 +1301,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } - /* vertex shader - still needed to specify mapping from fragment - * shader input semantics to vertex elements - */ - { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC }; - const uint semantic_indexes[] = { 0, 0 }; - ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes); - } - - /* fragment shader */ - ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D, - TGSI_INTERPOLATE_LINEAR); - ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR); - ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D, - TGSI_INTERPOLATE_LINEAR); - ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE, - TGSI_INTERPOLATE_LINEAR); - if (pipe->screen->get_param(pipe->screen, PIPE_CAP_ARRAY_TEXTURES)) { - ctx->fs1da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D_ARRAY, - TGSI_INTERPOLATE_LINEAR); - ctx->fs2da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D_ARRAY, - TGSI_INTERPOLATE_LINEAR); - } - - /* vertex data that doesn't change */ for (i = 0; i < 4; i++) { ctx->vertices[i][0][2] = 0.0f; /* z */ @@ -1342,6 +1314,44 @@ util_create_gen_mipmap(struct pipe_context *pipe, } +/** + * Helper function to set the fragment shaders. + */ +static INLINE void +set_fragment_shader(struct gen_mipmap_state *ctx, uint type) +{ + if (!ctx->fs[type]) + ctx->fs[type] = + util_make_fragment_tex_shader(ctx->pipe, type, + TGSI_INTERPOLATE_LINEAR); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs[type]); +} + + +/** + * Helper function to set the vertex shader. + */ +static INLINE void +set_vertex_shader(struct gen_mipmap_state *ctx) +{ + /* vertex shader - still required to provide the linkage between + * fragment shader input semantics and vertex_element/buffers. + */ + if (!ctx->vs) + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, + semantic_names, + semantic_indexes); + } + + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); +} + + /** * Get next "slot" of vertex space in the vertex buffer. * We're allocating one large vertex buffer and using it piece by piece. @@ -1450,16 +1460,14 @@ void util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) { struct pipe_context *pipe = ctx->pipe; + unsigned i; - if (ctx->fs2da) - pipe->delete_fs_state(pipe, ctx->fs2da); - if (ctx->fs1da) - pipe->delete_fs_state(pipe, ctx->fs1da); - pipe->delete_fs_state(pipe, ctx->fsCube); - pipe->delete_fs_state(pipe, ctx->fs3d); - pipe->delete_fs_state(pipe, ctx->fs2d); - pipe->delete_fs_state(pipe, ctx->fs1d); - pipe->delete_vs_state(pipe, ctx->vs); + for (i = 0; i < Elements(ctx->fs); i++) + if (ctx->fs[i]) + pipe->delete_fs_state(pipe, ctx->fs[i]); + + if (ctx->vs) + pipe->delete_vs_state(pipe, ctx->vs); pipe_resource_reference(&ctx->vbuf, NULL); @@ -1498,9 +1506,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_screen *screen = pipe->screen; struct pipe_framebuffer_state fb; struct pipe_resource *pt = psv->texture; - void *fs; uint dstLevel; uint offset; + uint type; /* The texture object should have room for the levels which we're * about to generate. @@ -1515,26 +1523,26 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, switch (pt->target) { case PIPE_TEXTURE_1D: - fs = ctx->fs1d; + type = TGSI_TEXTURE_1D; break; case PIPE_TEXTURE_2D: - fs = ctx->fs2d; + type = TGSI_TEXTURE_2D; break; case PIPE_TEXTURE_3D: - fs = ctx->fs3d; + type = TGSI_TEXTURE_3D; break; case PIPE_TEXTURE_CUBE: - fs = ctx->fsCube; + type = TGSI_TEXTURE_CUBE; break; case PIPE_TEXTURE_1D_ARRAY: - fs = ctx->fs1da; + type = TGSI_TEXTURE_1D_ARRAY; break; case PIPE_TEXTURE_2D_ARRAY: - fs = ctx->fs2da; + type = TGSI_TEXTURE_2D_ARRAY; break; default: assert(0); - fs = ctx->fs2d; + type = TGSI_TEXTURE_2D; } /* check if we can render in the texture's format */ @@ -1564,8 +1572,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); - cso_set_fragment_shader_handle(ctx->cso, fs); - cso_set_vertex_shader_handle(ctx->cso, ctx->vs); + set_fragment_shader(ctx, type); + set_vertex_shader(ctx); /* init framebuffer state */ memset(&fb, 0, sizeof(fb)); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 0e0c4326ed7..1eb748e0d5d 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -63,26 +63,12 @@ void st_init_clear(struct st_context *st) { - struct pipe_context *pipe = st->pipe; struct pipe_screen *pscreen = st->pipe->screen; memset(&st->clear, 0, sizeof(st->clear)); st->clear.raster.gl_rasterization_rules = 1; st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE); - - /* fragment shader state: color pass-through program */ - st->clear.fs = util_make_fragment_passthrough_shader(pipe); - - /* vertex shader state: color/position pass-through */ - { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_COLOR }; - const uint semantic_indexes[] = { 0, 0 }; - st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2, - semantic_names, - semantic_indexes); - } } @@ -107,6 +93,42 @@ st_destroy_clear(struct st_context *st) } +/** + * Helper function to set the fragment shaders. + */ +static INLINE void +set_fragment_shader(struct st_context *st) +{ + if (!st->clear.fs) + st->clear.fs = util_make_fragment_passthrough_shader(st->pipe); + + cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); +} + + +/** + * Helper function to set the vertex shader. + */ +static INLINE void +set_vertex_shader(struct st_context *st) +{ + /* vertex shader - still required to provide the linkage between + * fragment shader input semantics and vertex_element/buffers. + */ + if (!st->clear.vs) + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_COLOR }; + const uint semantic_indexes[] = { 0, 0 }; + st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2, + semantic_names, + semantic_indexes); + } + + cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); +} + + /** * Draw a screen-aligned quadrilateral. * Coords are clip coords with y=0=bottom. @@ -297,8 +319,8 @@ clear_with_quad(struct gl_context *ctx, } cso_set_clip(st->cso_context, &st->clear.clip); - cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); - cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); + set_fragment_shader(st); + set_vertex_shader(st); if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { st_translate_color(ctx->Color.ClearColor,