static void brw_upload_gs_prog(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; struct brw_stage_state *stage_state = &brw->gs.base; struct brw_gs_prog_key key; /* BRW_NEW_GEOMETRY_PROGRAM */ struct brw_geometry_program *gp = (struct brw_geometry_program *) brw->geometry_program; if (gp == NULL) { /* No geometry shader. Vertex data just passes straight through. */ if (brw->state.dirty.brw & BRW_NEW_VUE_MAP_VS) { brw->vue_map_geom_out = brw->vue_map_vs; brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT; } return; } struct gl_program *prog = &gp->program.Base; memset(&key, 0, sizeof(key)); key.base.program_string_id = gp->id; brw_setup_vec4_key_clip_info(brw, &key.base, gp->program.Base.UsesClipDistanceOut); /* _NEW_LIGHT | _NEW_BUFFERS */ key.base.clamp_vertex_color = ctx->Light._ClampVertexColor; /* _NEW_TEXTURE */ brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count, &key.base.tex); /* BRW_NEW_VUE_MAP_VS */ key.input_varyings = brw->vue_map_vs.slots_valid; if (!brw_search_cache(&brw->cache, BRW_GS_PROG, &key, sizeof(key), &stage_state->prog_offset, &brw->gs.prog_data)) { bool success = do_gs_prog(brw, ctx->Shader.CurrentGeometryProgram, gp, &key); assert(success); } brw->gs.base.prog_data = &brw->gs.prog_data->base.base; if (memcmp(&brw->vs.prog_data->base.vue_map, &brw->vue_map_geom_out, sizeof(brw->vue_map_geom_out)) != 0) { brw->vue_map_geom_out = brw->gs.prog_data->base.vue_map; brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT; } }
static void brw_upload_vs_prog(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; struct brw_vs_prog_key key; /* BRW_NEW_VERTEX_PROGRAM */ struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program; struct gl_program *prog = (struct gl_program *) brw->vertex_program; int i; memset(&key, 0, sizeof(key)); /* Just upload the program verbatim for now. Always send it all * the inputs it asks for, whether they are varying or not. */ key.base.program_string_id = vp->id; brw_setup_vec4_key_clip_info(brw, &key.base, vp->program.Base.UsesClipDistanceOut); /* _NEW_POLYGON */ if (brw->gen < 6) { key.copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL); } /* _NEW_LIGHT | _NEW_BUFFERS */ key.base.clamp_vertex_color = ctx->Light._ClampVertexColor; /* _NEW_POINT */ if (brw->gen < 6 && ctx->Point.PointSprite) { for (i = 0; i < 8; i++) { if (ctx->Point.CoordReplace[i]) key.point_coord_replace |= (1 << i); } } /* _NEW_TEXTURE */ brw_populate_sampler_prog_key_data(ctx, prog, brw->vs.base.sampler_count, &key.base.tex); /* BRW_NEW_VERTICES */ if (brw->gen < 8 && !brw->is_haswell) { /* Prior to Haswell, the hardware can't natively support GL_FIXED or * 2_10_10_10_REV vertex formats. Set appropriate workaround flags. */ for (i = 0; i < VERT_ATTRIB_MAX; i++) { if (!(vp->program.Base.InputsRead & BITFIELD64_BIT(i))) continue; uint8_t wa_flags = 0; switch (brw->vb.inputs[i].glarray->Type) { case GL_FIXED: wa_flags = brw->vb.inputs[i].glarray->Size; break; case GL_INT_2_10_10_10_REV: wa_flags |= BRW_ATTRIB_WA_SIGN; /* fallthough */ case GL_UNSIGNED_INT_2_10_10_10_REV: if (brw->vb.inputs[i].glarray->Format == GL_BGRA) wa_flags |= BRW_ATTRIB_WA_BGRA; if (brw->vb.inputs[i].glarray->Normalized) wa_flags |= BRW_ATTRIB_WA_NORMALIZE; else if (!brw->vb.inputs[i].glarray->Integer) wa_flags |= BRW_ATTRIB_WA_SCALE; break; } key.gl_attrib_wa_flags[i] = wa_flags; } } if (!brw_search_cache(&brw->cache, BRW_VS_PROG, &key, sizeof(key), &brw->vs.base.prog_offset, &brw->vs.prog_data)) { bool success = do_vs_prog(brw, ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX], vp, &key); (void) success; assert(success); } brw->vs.base.prog_data = &brw->vs.prog_data->base.base; if (memcmp(&brw->vs.prog_data->base.vue_map, &brw->vue_map_geom_out, sizeof(brw->vue_map_geom_out)) != 0) { brw->vue_map_vs = brw->vs.prog_data->base.vue_map; brw->state.dirty.brw |= BRW_NEW_VUE_MAP_VS; if (brw->gen < 7) { /* No geometry shader support, so the VS VUE map is the VUE map for * the output of the "geometry" portion of the pipeline. */ brw->vue_map_geom_out = brw->vue_map_vs; brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT; } } }