X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_program.c;h=555fc5d5ad9bc3c7c4f55a5d7b91d4c7448d0a8d;hb=86d63b53a20a747e3de769549572d895c7fbb736;hp=5138e596a9c35f1396b1aa04067d566e6042da88;hpb=43867acb6afc7fad26cdc2f22b2a3bb6eeefb2da;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 5138e596a9c..555fc5d5ad9 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2003 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -27,100 +27,59 @@ /* * Authors: - * Keith Whitwell + * Keith Whitwell */ #include "main/glheader.h" #include "main/macros.h" #include "main/enums.h" -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/program.h" -#include "shader/shader_api.h" +#include "main/shaderapi.h" +#include "program/prog_instruction.h" +#include "program/program.h" #include "cso_cache/cso_context.h" #include "draw/draw_context.h" #include "st_context.h" +#include "st_debug.h" #include "st_program.h" -#include "st_atom_shader.h" #include "st_mesa_to_tgsi.h" #include "st_cb_program.h" - - -static GLuint SerialNo = 1; - - -/** - * Called via ctx->Driver.BindProgram() to bind an ARB vertex or - * fragment program. - */ -static void st_bind_program( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) -{ - struct st_context *st = st_context(ctx); - - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - st->dirty.st |= ST_NEW_VERTEX_PROGRAM; - break; - case GL_FRAGMENT_PROGRAM_ARB: - st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; - break; - } -} - - -/** - * Called via ctx->Driver.UseProgram() to bind a linked GLSL program - * (vertex shader + fragment shader). - */ -static void st_use_program( GLcontext *ctx, - GLuint program ) -{ - struct st_context *st = st_context(ctx); - - st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; - st->dirty.st |= ST_NEW_VERTEX_PROGRAM; - - _mesa_use_program(ctx, program); -} - +#include "st_glsl_to_tgsi.h" +#include "st_atifs_to_tgsi.h" /** * Called via ctx->Driver.NewProgram() to allocate a new vertex or * fragment program. */ -static struct gl_program *st_new_program( GLcontext *ctx, - GLenum target, - GLuint id ) +static struct gl_program * +st_new_program(struct gl_context *ctx, GLenum target, GLuint id, + bool is_arb_asm) { switch (target) { case GL_VERTEX_PROGRAM_ARB: { - struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program); - - prog->serialNo = SerialNo++; - - return _mesa_init_vertex_program( ctx, - &prog->Base, - target, - id ); + struct st_vertex_program *prog = rzalloc(NULL, + struct st_vertex_program); + return _mesa_init_gl_program(&prog->Base, target, id, is_arb_asm); } - - case GL_FRAGMENT_PROGRAM_ARB: - case GL_FRAGMENT_PROGRAM_NV: { - struct st_fragment_program *prog = ST_CALLOC_STRUCT(st_fragment_program); - - prog->serialNo = SerialNo++; - - return _mesa_init_fragment_program( ctx, - &prog->Base, - target, - id ); + case GL_FRAGMENT_PROGRAM_ARB: { + struct st_fragment_program *prog = rzalloc(NULL, + struct st_fragment_program); + return _mesa_init_gl_program(&prog->Base, target, id, is_arb_asm); + } + case GL_TESS_CONTROL_PROGRAM_NV: + case GL_TESS_EVALUATION_PROGRAM_NV: + case GL_GEOMETRY_PROGRAM_NV: { + struct st_common_program *prog = rzalloc(NULL, + struct st_common_program); + return _mesa_init_gl_program(&prog->Base, target, id, is_arb_asm); + } + case GL_COMPUTE_PROGRAM_NV: { + struct st_compute_program *prog = rzalloc(NULL, + struct st_compute_program); + return _mesa_init_gl_program(&prog->Base, target, id, is_arb_asm); } - default: assert(0); return NULL; @@ -128,8 +87,11 @@ static struct gl_program *st_new_program( GLcontext *ctx, } -void -st_delete_program(GLcontext *ctx, struct gl_program *prog) +/** + * Called via ctx->Driver.DeleteProgram() + */ +static void +st_delete_program(struct gl_context *ctx, struct gl_program *prog) { struct st_context *st = st_context(ctx); @@ -137,28 +99,45 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) case GL_VERTEX_PROGRAM_ARB: { struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - st_vp_release_varients( st, stvp ); + st_release_vp_variants( st, stvp ); + + if (stvp->glsl_to_tgsi) + free_glsl_to_tgsi_visitor(stvp->glsl_to_tgsi); + } + break; + case GL_TESS_CONTROL_PROGRAM_NV: + case GL_TESS_EVALUATION_PROGRAM_NV: + case GL_GEOMETRY_PROGRAM_NV: + { + struct st_common_program *p = st_common_program(prog); + + st_release_basic_variants(st, p->Base.Target, &p->variants, + &p->tgsi); + + if (p->glsl_to_tgsi) + free_glsl_to_tgsi_visitor(p->glsl_to_tgsi); } break; case GL_FRAGMENT_PROGRAM_ARB: { - struct st_fragment_program *stfp = (struct st_fragment_program *) prog; + struct st_fragment_program *stfp = + (struct st_fragment_program *) prog; - if (stfp->driver_shader) { - cso_delete_fragment_shader(st->cso_context, stfp->driver_shader); - stfp->driver_shader = NULL; - } + st_release_fp_variants(st, stfp); - if (stfp->state.tokens) { - st_free_tokens(stfp->state.tokens); - stfp->state.tokens = NULL; - } - - if (stfp->bitmap_program) { - struct gl_program *prg = &stfp->bitmap_program->Base.Base; - _mesa_reference_program(ctx, &prg, NULL); - stfp->bitmap_program = NULL; - } + if (stfp->glsl_to_tgsi) + free_glsl_to_tgsi_visitor(stfp->glsl_to_tgsi); + } + break; + case GL_COMPUTE_PROGRAM_NV: + { + struct st_compute_program *stcp = + (struct st_compute_program *) prog; + + st_release_cp_variants(st, stcp); + + if (stcp->glsl_to_tgsi) + free_glsl_to_tgsi_visitor(stcp->glsl_to_tgsi); } break; default: @@ -170,58 +149,133 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) } -static GLboolean st_is_program_native( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) -{ - return GL_TRUE; -} - - -static void st_program_string_notify( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) +/** + * Called via ctx->Driver.ProgramStringNotify() + * Called when the program's text/code is changed. We have to free + * all shader variants and corresponding gallium shaders when this happens. + */ +static GLboolean +st_program_string_notify( struct gl_context *ctx, + GLenum target, + struct gl_program *prog ) { struct st_context *st = st_context(ctx); + gl_shader_stage stage = _mesa_program_enum_to_shader_stage(target); if (target == GL_FRAGMENT_PROGRAM_ARB) { struct st_fragment_program *stfp = (struct st_fragment_program *) prog; - stfp->serialNo++; + st_release_fp_variants(st, stfp); + if (!st_translate_fragment_program(st, stfp)) + return false; - if (stfp->driver_shader) { - cso_delete_fragment_shader(st->cso_context, stfp->driver_shader); - stfp->driver_shader = NULL; - } + if (st->fp == stfp) + st->dirty |= stfp->affected_states; + } + else if (target == GL_GEOMETRY_PROGRAM_NV) { + struct st_common_program *stgp = st_common_program(prog); - if (stfp->state.tokens) { - st_free_tokens(stfp->state.tokens); - stfp->state.tokens = NULL; - } + st_release_basic_variants(st, stgp->Base.Target, &stgp->variants, + &stgp->tgsi); + if (!st_translate_geometry_program(st, stgp)) + return false; - if (st->fp == stfp) - st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; + if (st->gp == stgp) + st->dirty |= stgp->affected_states; } else if (target == GL_VERTEX_PROGRAM_ARB) { struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - stvp->serialNo++; - - st_vp_release_varients( st, stvp ); + st_release_vp_variants(st, stvp); + if (!st_translate_vertex_program(st, stvp)) + return false; if (st->vp == stvp) - st->dirty.st |= ST_NEW_VERTEX_PROGRAM; + st->dirty |= ST_NEW_VERTEX_PROGRAM(st, stvp); } -} + else if (target == GL_TESS_CONTROL_PROGRAM_NV) { + struct st_common_program *sttcp = + st_common_program(prog); + + st_release_basic_variants(st, sttcp->Base.Target, &sttcp->variants, + &sttcp->tgsi); + if (!st_translate_tessctrl_program(st, sttcp)) + return false; + + if (st->tcp == sttcp) + st->dirty |= sttcp->affected_states; + } + else if (target == GL_TESS_EVALUATION_PROGRAM_NV) { + struct st_common_program *sttep = + st_common_program(prog); + + st_release_basic_variants(st, sttep->Base.Target, &sttep->variants, + &sttep->tgsi); + if (!st_translate_tesseval_program(st, sttep)) + return false; + if (st->tep == sttep) + st->dirty |= sttep->affected_states; + } + else if (target == GL_COMPUTE_PROGRAM_NV) { + struct st_compute_program *stcp = + (struct st_compute_program *) prog; + + st_release_cp_variants(st, stcp); + if (!st_translate_compute_program(st, stcp)) + return false; + + if (st->cp == stcp) + st->dirty |= stcp->affected_states; + } + else if (target == GL_FRAGMENT_SHADER_ATI) { + assert(prog); + + struct st_fragment_program *stfp = (struct st_fragment_program *) prog; + assert(stfp->ati_fs); + assert(stfp->ati_fs->Program == prog); + + st_init_atifs_prog(ctx, prog); + + st_release_fp_variants(st, stfp); + if (!st_translate_fragment_program(st, stfp)) + return false; + + if (st->fp == stfp) + st->dirty |= stfp->affected_states; + } + if (ST_DEBUG & DEBUG_PRECOMPILE || + st->shader_has_one_variant[stage]) + st_precompile_shader_variant(st, prog); -void st_init_program_functions(struct dd_function_table *functions) + return GL_TRUE; +} + +/** + * Called via ctx->Driver.NewATIfs() + * Called in glEndFragmentShaderATI() + */ +static struct gl_program * +st_new_ati_fs(struct gl_context *ctx, struct ati_fragment_shader *curProg) +{ + struct gl_program *prog = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, + curProg->Id, true); + struct st_fragment_program *stfp = (struct st_fragment_program *)prog; + stfp->ati_fs = curProg; + return prog; +} + +/** + * Plug in the program and shader-related device driver functions. + */ +void +st_init_program_functions(struct dd_function_table *functions) { - functions->BindProgram = st_bind_program; - functions->UseProgram = st_use_program; functions->NewProgram = st_new_program; functions->DeleteProgram = st_delete_program; - functions->IsProgramNative = st_is_program_native; functions->ProgramStringNotify = st_program_string_notify; + functions->NewATIfs = st_new_ati_fs; + + functions->LinkShader = st_link_shader; }