static GLboolean brwProgramStringNotify(struct gl_context *ctx, GLenum target, struct gl_program *prog) { assert(target == GL_VERTEX_PROGRAM_ARB || !prog->arb.IsPositionInvariant); struct brw_context *brw = brw_context(ctx); const struct brw_compiler *compiler = brw->screen->compiler; switch (target) { case GL_FRAGMENT_PROGRAM_ARB: { struct brw_program *newFP = brw_program(prog); const struct brw_program *curFP = brw_program_const(brw->fragment_program); if (newFP == curFP) brw->ctx.NewDriverState |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = get_new_program_id(brw->screen); prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_FRAGMENT, true); brw_fs_precompile(ctx, prog); break; } case GL_VERTEX_PROGRAM_ARB: { struct brw_program *newVP = brw_program(prog); const struct brw_program *curVP = brw_program_const(brw->vertex_program); if (newVP == curVP) brw->ctx.NewDriverState |= BRW_NEW_VERTEX_PROGRAM; if (newVP->program.arb.IsPositionInvariant) { _mesa_insert_mvp_code(ctx, &newVP->program); } newVP->id = get_new_program_id(brw->screen); /* Also tell tnl about it: */ _tnl_program_string(ctx, target, prog); prog->nir = brw_create_nir(brw, NULL, prog, MESA_SHADER_VERTEX, compiler->scalar_stage[MESA_SHADER_VERTEX]); brw_vs_precompile(ctx, prog); break; } default: /* * driver->ProgramStringNotify is only called for ARB programs, fixed * function vertex programs, and ir_to_mesa (which isn't used by the * i965 back-end). Therefore, even after geometry shaders are added, * this function should only ever be called with a target of * GL_VERTEX_PROGRAM_ARB or GL_FRAGMENT_PROGRAM_ARB. */ unreachable("Unexpected target in brwProgramStringNotify"); } return true; }
bool brw_fs_precompile(struct gl_context *ctx, struct gl_program *prog) { struct brw_context *brw = brw_context(ctx); const struct gen_device_info *devinfo = &brw->screen->devinfo; struct brw_wm_prog_key key; struct brw_program *bfp = brw_program(prog); brw_wm_populate_default_key(&brw->screen->devinfo, &key, prog); /* check brw_wm_populate_default_key coherent_fb_fetch setting */ assert(key.coherent_fb_fetch == ctx->Extensions.EXT_shader_framebuffer_fetch); uint32_t old_prog_offset = brw->wm.base.prog_offset; struct brw_stage_prog_data *old_prog_data = brw->wm.base.prog_data; struct brw_vue_map vue_map; if (devinfo->gen < 6) { brw_compute_vue_map(&brw->screen->devinfo, &vue_map, prog->info.inputs_read | VARYING_BIT_POS, false); } bool success = brw_codegen_wm_prog(brw, bfp, &key, &vue_map); brw->wm.base.prog_offset = old_prog_offset; brw->wm.base.prog_data = old_prog_data; return success; }
bool brw_cs_precompile(struct gl_context *ctx, struct gl_shader_program *shader_prog, struct gl_program *prog) { struct brw_context *brw = brw_context(ctx); struct brw_cs_prog_key key; struct brw_program *bcp = brw_program(prog); memset(&key, 0, sizeof(key)); key.program_string_id = bcp->id; brw_setup_tex_for_precompile(brw, &key.tex, prog); uint32_t old_prog_offset = brw->cs.base.prog_offset; struct brw_stage_prog_data *old_prog_data = brw->cs.base.prog_data; bool success = brw_codegen_cs_prog(brw, shader_prog, bcp, &key); brw->cs.base.prog_offset = old_prog_offset; brw->cs.base.prog_data = old_prog_data; return success; }
bool brw_tes_precompile(struct gl_context *ctx, struct gl_shader_program *shader_prog, struct gl_program *prog) { struct brw_context *brw = brw_context(ctx); struct brw_tes_prog_key key; uint32_t old_prog_offset = brw->tes.base.prog_offset; struct brw_stage_prog_data *old_prog_data = brw->tes.base.prog_data; bool success; struct brw_program *btep = brw_program(prog); brw_tes_populate_default_key(&brw->screen->devinfo, &key, shader_prog, prog); success = brw_codegen_tes_prog(brw, btep, &key); brw->tes.base.prog_offset = old_prog_offset; brw->tes.base.prog_data = old_prog_data; return success; }
void brw_wm_populate_default_key(const struct gen_device_info *devinfo, struct brw_wm_prog_key *key, struct gl_program *prog) { memset(key, 0, sizeof(*key)); uint64_t outputs_written = prog->info.outputs_written; if (devinfo->gen < 6) { if (prog->info.fs.uses_discard) key->iz_lookup |= BRW_WM_IZ_PS_KILL_ALPHATEST_BIT; if (outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) key->iz_lookup |= BRW_WM_IZ_PS_COMPUTES_DEPTH_BIT; /* Just assume depth testing. */ key->iz_lookup |= BRW_WM_IZ_DEPTH_TEST_ENABLE_BIT; key->iz_lookup |= BRW_WM_IZ_DEPTH_WRITE_ENABLE_BIT; } if (devinfo->gen < 6 || util_bitcount64(prog->info.inputs_read & BRW_FS_VARYING_INPUT_MASK) > 16) { key->input_slots_valid = prog->info.inputs_read | VARYING_BIT_POS; } brw_setup_tex_for_precompile(devinfo, &key->tex, prog); key->nr_color_regions = util_bitcount64(outputs_written & ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) | BITFIELD64_BIT(FRAG_RESULT_STENCIL) | BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK))); key->program_string_id = brw_program(prog)->id; /* Whether reads from the framebuffer should behave coherently. */ key->coherent_fb_fetch = devinfo->gen >= 9; }
void brw_tes_populate_default_key(const struct gen_device_info *devinfo, struct brw_tes_prog_key *key, struct gl_shader_program *sh_prog, struct gl_program *prog) { struct brw_program *btep = brw_program(prog); memset(key, 0, sizeof(*key)); key->program_string_id = btep->id; key->inputs_read = prog->nir->info.inputs_read; key->patch_inputs_read = prog->nir->info.patch_inputs_read; if (sh_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]) { struct gl_program *tcp = sh_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program; key->inputs_read |= tcp->nir->info.outputs_written & ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); key->patch_inputs_read |= tcp->nir->info.patch_outputs_written; } brw_setup_tex_for_precompile(devinfo, &key->tex, prog); }