X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_cb_program.c;h=f01e1374ebf1ee31490ac739d766588f22fd183e;hb=500b0735c0caa293d22fb3728cb76d267a016834;hp=2c4eccf1e06ec47ae5162de72fcee38821fd27b0;hpb=fed60e3c73c7be7c1e2194054daf29381d0ddc18;p=mesa.git diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 2c4eccf1e06..f01e1374ebf 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -45,88 +45,31 @@ #include "st_program.h" #include "st_mesa_to_tgsi.h" #include "st_cb_program.h" -#include "st_glsl_to_tgsi.h" - +#include "st_glsl_to_ir.h" +#include "st_atifs_to_tgsi.h" +#include "st_util.h" /** - * Called via ctx->Driver.BindProgram() to bind an ARB vertex or + * Called via ctx->Driver.NewProgram() to allocate a new vertex or * fragment program. */ -static void -st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog) +static struct gl_program * +st_new_program(struct gl_context *ctx, gl_shader_stage stage, GLuint id, + bool is_arb_asm) { - struct st_context *st = st_context(ctx); + struct st_program *prog; - 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; + switch (stage) { + case MESA_SHADER_VERTEX: + prog = (struct st_program*)rzalloc(NULL, struct st_vertex_program); break; - case GL_GEOMETRY_PROGRAM_NV: - st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM; - break; - case GL_TESS_CONTROL_PROGRAM_NV: - st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM; - break; - case GL_TESS_EVALUATION_PROGRAM_NV: - st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM; + default: + prog = rzalloc(NULL, struct st_program); break; } -} - -/** - * Called via ctx->Driver.UseProgram() to bind a linked GLSL program - * (vertex shader + fragment shader). - */ -static void -st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) -{ - struct st_context *st = st_context(ctx); - - st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; - st->dirty.st |= ST_NEW_VERTEX_PROGRAM; - st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM; - st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM; - st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM; -} - - -/** - * Called via ctx->Driver.NewProgram() to allocate a new vertex or - * fragment program. - */ -static struct gl_program * -st_new_program(struct gl_context *ctx, GLenum target, GLuint id) -{ - switch (target) { - case GL_VERTEX_PROGRAM_ARB: { - struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program); - return _mesa_init_gl_program(&prog->Base.Base, target, id); - } - case GL_FRAGMENT_PROGRAM_ARB: { - struct st_fragment_program *prog = ST_CALLOC_STRUCT(st_fragment_program); - return _mesa_init_gl_program(&prog->Base.Base, target, id); - } - case GL_GEOMETRY_PROGRAM_NV: { - struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program); - return _mesa_init_gl_program(&prog->Base.Base, target, id); - } - case GL_TESS_CONTROL_PROGRAM_NV: { - struct st_tessctrl_program *prog = ST_CALLOC_STRUCT(st_tessctrl_program); - return _mesa_init_gl_program(&prog->Base.Base, target, id); - } - case GL_TESS_EVALUATION_PROGRAM_NV: { - struct st_tesseval_program *prog = ST_CALLOC_STRUCT(st_tesseval_program); - return _mesa_init_gl_program(&prog->Base.Base, target, id); - } - default: - assert(0); - return NULL; - } + return _mesa_init_gl_program(&prog->Base, stage, id, is_arb_asm); } @@ -137,82 +80,19 @@ static void st_delete_program(struct gl_context *ctx, struct gl_program *prog) { struct st_context *st = st_context(ctx); + struct st_program *stp = st_program(prog); - switch( prog->Target ) { - case GL_VERTEX_PROGRAM_ARB: - { - struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - st_release_vp_variants( st, stvp ); - - if (stvp->glsl_to_tgsi) - free_glsl_to_tgsi_visitor(stvp->glsl_to_tgsi); - } - break; - case GL_GEOMETRY_PROGRAM_NV: - { - struct st_geometry_program *stgp = - (struct st_geometry_program *) prog; - - st_release_gp_variants(st, stgp); - - if (stgp->glsl_to_tgsi) - free_glsl_to_tgsi_visitor(stgp->glsl_to_tgsi); - } - break; - case GL_FRAGMENT_PROGRAM_ARB: - { - struct st_fragment_program *stfp = - (struct st_fragment_program *) prog; - - st_release_fp_variants(st, stfp); - - if (stfp->glsl_to_tgsi) - free_glsl_to_tgsi_visitor(stfp->glsl_to_tgsi); - } - break; - case GL_TESS_CONTROL_PROGRAM_NV: - { - struct st_tessctrl_program *sttcp = - (struct st_tessctrl_program *) prog; + st_release_variants(st, stp); - st_release_tcp_variants(st, sttcp); + if (stp->glsl_to_tgsi) + free_glsl_to_tgsi_visitor(stp->glsl_to_tgsi); - if (sttcp->glsl_to_tgsi) - free_glsl_to_tgsi_visitor(sttcp->glsl_to_tgsi); - } - break; - case GL_TESS_EVALUATION_PROGRAM_NV: - { - struct st_tesseval_program *sttep = - (struct st_tesseval_program *) prog; - - st_release_tep_variants(st, sttep); - - if (sttep->glsl_to_tgsi) - free_glsl_to_tgsi_visitor(sttep->glsl_to_tgsi); - } - break; - default: - assert(0); /* problem */ - } + free(stp->serialized_nir); /* delete base class */ _mesa_delete_program( ctx, prog ); } - -/** - * Called via ctx->Driver.IsProgramNative() - */ -static GLboolean -st_is_program_native(struct gl_context *ctx, - GLenum target, - struct gl_program *prog) -{ - return GL_TRUE; -} - - /** * Called via ctx->Driver.ProgramStringNotify() * Called when the program's text/code is changed. We have to free @@ -224,68 +104,86 @@ st_program_string_notify( struct gl_context *ctx, struct gl_program *prog ) { struct st_context *st = st_context(ctx); - gl_shader_stage stage = _mesa_program_enum_to_shader_stage(target); + struct st_program *stp = (struct st_program *) prog; - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct st_fragment_program *stfp = (struct st_fragment_program *) prog; + /* GLSL-to-NIR should not end up here. */ + assert(!stp->shader_program); - st_release_fp_variants(st, stfp); - if (!st_translate_fragment_program(st, stfp)) - return false; + st_release_variants(st, stp); - if (st->fp == stfp) - st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; - } - else if (target == GL_GEOMETRY_PROGRAM_NV) { - struct st_geometry_program *stgp = (struct st_geometry_program *) prog; + if (target == GL_FRAGMENT_PROGRAM_ARB || + target == GL_FRAGMENT_SHADER_ATI) { + if (target == GL_FRAGMENT_SHADER_ATI) { + assert(stp->ati_fs); + assert(stp->ati_fs->Program == prog); - st_release_gp_variants(st, stgp); - if (!st_translate_geometry_program(st, stgp)) - return false; + st_init_atifs_prog(ctx, prog); + } - if (st->gp == stgp) - st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM; + if (!st_translate_fragment_program(st, stp)) + return false; + } else if (target == GL_VERTEX_PROGRAM_ARB) { + if (!st_translate_vertex_program(st, stp)) + return false; + } else { + if (!st_translate_common_program(st, stp)) + return false; } - else if (target == GL_VERTEX_PROGRAM_ARB) { - struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - st_release_vp_variants(st, stvp); - if (!st_translate_vertex_program(st, stvp)) - return false; + st_finalize_program(st, prog); + return GL_TRUE; +} - if (st->vp == stvp) - st->dirty.st |= ST_NEW_VERTEX_PROGRAM; - } - else if (target == GL_TESS_CONTROL_PROGRAM_NV) { - struct st_tessctrl_program *sttcp = - (struct st_tessctrl_program *) prog; +/** + * 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, MESA_SHADER_FRAGMENT, + curProg->Id, true); + struct st_program *stfp = (struct st_program *)prog; + stfp->ati_fs = curProg; + return prog; +} - st_release_tcp_variants(st, sttcp); - if (!st_translate_tessctrl_program(st, sttcp)) - return false; +static void +st_max_shader_compiler_threads(struct gl_context *ctx, unsigned count) +{ + struct pipe_screen *screen = st_context(ctx)->pipe->screen; - if (st->tcp == sttcp) - st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM; - } - else if (target == GL_TESS_EVALUATION_PROGRAM_NV) { - struct st_tesseval_program *sttep = - (struct st_tesseval_program *) prog; + if (screen->set_max_shader_compiler_threads) + screen->set_max_shader_compiler_threads(screen, count); +} - st_release_tep_variants(st, sttep); - if (!st_translate_tesseval_program(st, sttep)) - return false; +static bool +st_get_shader_program_completion_status(struct gl_context *ctx, + struct gl_shader_program *shprog) +{ + struct pipe_screen *screen = st_context(ctx)->pipe->screen; - if (st->tep == sttep) - st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM; - } + if (!screen->is_parallel_shader_compilation_finished) + return true; - if (ST_DEBUG & DEBUG_PRECOMPILE || - st->shader_has_one_variant[stage]) - st_precompile_shader_variant(st, prog); + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + struct gl_linked_shader *linked = shprog->_LinkedShaders[i]; + void *sh = NULL; - return GL_TRUE; -} + if (!linked || !linked->Program) + continue; + if (st_program(linked->Program)->variants) + sh = st_program(linked->Program)->variants->driver_shader; + + unsigned type = pipe_shader_type_from_mesa(i); + + if (sh && + !screen->is_parallel_shader_compilation_finished(screen, sh, type)) + return false; + } + return true; +} /** * Plug in the program and shader-related device driver functions. @@ -293,12 +191,12 @@ st_program_string_notify( struct gl_context *ctx, 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; + functions->SetMaxShaderCompilerThreads = st_max_shader_compiler_threads; + functions->GetShaderProgramCompletionStatus = + st_get_shader_program_completion_status; }