/* Calculate interpolants for triangle and line rasterization. */ static void upload_sf_prog(struct brw_context *brw) { GLcontext *ctx = &brw->intel.ctx; struct brw_sf_prog_key key; memset(&key, 0, sizeof(key)); /* Populate the key, noting state dependencies: */ /* CACHE_NEW_VS_PROG */ key.attrs = brw->vs.prog_data->outputs_written; /* BRW_NEW_REDUCED_PRIMITIVE */ switch (brw->intel.reduced_primitive) { case GL_TRIANGLES: /* NOTE: We just use the edgeflag attribute as an indicator that * unfilled triangles are active. We don't actually do the * edgeflag testing here, it is already done in the clip * program. */ if (key.attrs & (1<<VERT_RESULT_EDGE)) key.primitive = SF_UNFILLED_TRIS; else key.primitive = SF_TRIANGLES; break; case GL_LINES: key.primitive = SF_LINES; break; case GL_POINTS: key.primitive = SF_POINTS; break; } key.do_point_sprite = ctx->Point.PointSprite; key.SpriteOrigin = ctx->Point.SpriteOrigin; /* _NEW_LIGHT */ key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT); key.do_twoside_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide); /* _NEW_POLYGON */ if (key.do_twoside_color) { /* If we're rendering to a FBO, we have to invert the polygon * face orientation, just as we invert the viewport in * sf_unit_create_from_key(). ctx->DrawBuffer->Name will be * nonzero if we're rendering to such an FBO. */ key.frontface_ccw = (ctx->Polygon.FrontFace == GL_CCW) ^ (ctx->DrawBuffer->Name != 0); } dri_bo_unreference(brw->sf.prog_bo); brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG, &key, sizeof(key), NULL, 0, &brw->sf.prog_data); if (brw->sf.prog_bo == NULL) compile_sf_prog( brw, &key ); }
/* Calculate interpolants for triangle and line rasterization. */ void brw_upload_sf_prog(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; struct brw_sf_prog_key key; if (!brw_state_dirty(brw, _NEW_BUFFERS | _NEW_HINT | _NEW_LIGHT | _NEW_POINT | _NEW_POLYGON | _NEW_PROGRAM | _NEW_TRANSFORM, BRW_NEW_BLORP | BRW_NEW_FS_PROG_DATA | BRW_NEW_REDUCED_PRIMITIVE | BRW_NEW_VUE_MAP_GEOM_OUT)) return; /* _NEW_BUFFERS */ bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer); memset(&key, 0, sizeof(key)); /* Populate the key, noting state dependencies: */ /* BRW_NEW_VUE_MAP_GEOM_OUT */ key.attrs = brw->vue_map_geom_out.slots_valid; /* BRW_NEW_REDUCED_PRIMITIVE */ switch (brw->reduced_primitive) { case GL_TRIANGLES: /* NOTE: We just use the edgeflag attribute as an indicator that * unfilled triangles are active. We don't actually do the * edgeflag testing here, it is already done in the clip * program. */ if (key.attrs & BITFIELD64_BIT(VARYING_SLOT_EDGE)) key.primitive = BRW_SF_PRIM_UNFILLED_TRIS; else key.primitive = BRW_SF_PRIM_TRIANGLES; break; case GL_LINES: key.primitive = BRW_SF_PRIM_LINES; break; case GL_POINTS: key.primitive = BRW_SF_PRIM_POINTS; break; } /* _NEW_TRANSFORM */ key.userclip_active = (ctx->Transform.ClipPlanesEnabled != 0); /* _NEW_POINT */ key.do_point_sprite = ctx->Point.PointSprite; if (key.do_point_sprite) { key.point_sprite_coord_replace = ctx->Point.CoordReplace & 0xff; } if (brw->programs[MESA_SHADER_FRAGMENT]->info.inputs_read & BITFIELD64_BIT(VARYING_SLOT_PNTC)) { key.do_point_coord = 1; } /* * Window coordinates in a FBO are inverted, which means point * sprite origin must be inverted, too. */ if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) key.sprite_origin_lower_left = true; /* BRW_NEW_FS_PROG_DATA */ const struct brw_wm_prog_data *wm_prog_data = brw_wm_prog_data(brw->wm.base.prog_data); if (wm_prog_data) { key.contains_flat_varying = wm_prog_data->contains_flat_varying; STATIC_ASSERT(sizeof(key.interp_mode) == sizeof(wm_prog_data->interp_mode)); memcpy(key.interp_mode, wm_prog_data->interp_mode, sizeof(key.interp_mode)); } /* _NEW_LIGHT | _NEW_PROGRAM */ key.do_twoside_color = _mesa_vertex_program_two_side_enabled(ctx); /* _NEW_POLYGON */ if (key.do_twoside_color) { /* If we're rendering to a FBO, we have to invert the polygon * face orientation, just as we invert the viewport in * sf_unit_create_from_key(). */ key.frontface_ccw = brw->polygon_front_bit == render_to_fbo; } if (!brw_search_cache(&brw->cache, BRW_CACHE_SF_PROG, &key, sizeof(key), &brw->sf.prog_offset, &brw->sf.prog_data)) { compile_sf_prog( brw, &key ); } }
/* Calculate interpolants for triangle and line rasterization. */ static void brw_upload_sf_prog(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; struct brw_sf_prog_key key; /* _NEW_BUFFERS */ bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer); memset(&key, 0, sizeof(key)); /* Populate the key, noting state dependencies: */ /* BRW_NEW_VUE_MAP_GEOM_OUT */ key.attrs = brw->vue_map_geom_out.slots_valid; /* BRW_NEW_REDUCED_PRIMITIVE */ switch (brw->reduced_primitive) { case GL_TRIANGLES: /* NOTE: We just use the edgeflag attribute as an indicator that * unfilled triangles are active. We don't actually do the * edgeflag testing here, it is already done in the clip * program. */ if (key.attrs & BITFIELD64_BIT(VARYING_SLOT_EDGE)) key.primitive = SF_UNFILLED_TRIS; else key.primitive = SF_TRIANGLES; break; case GL_LINES: key.primitive = SF_LINES; break; case GL_POINTS: key.primitive = SF_POINTS; break; } /* _NEW_TRANSFORM */ key.userclip_active = (ctx->Transform.ClipPlanesEnabled != 0); /* _NEW_POINT */ key.do_point_sprite = ctx->Point.PointSprite; if (key.do_point_sprite) { int i; for (i = 0; i < 8; i++) { if (ctx->Point.CoordReplace[i]) key.point_sprite_coord_replace |= (1 << i); } } if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(VARYING_SLOT_PNTC)) key.do_point_coord = 1; /* * Window coordinates in a FBO are inverted, which means point * sprite origin must be inverted, too. */ if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) key.sprite_origin_lower_left = true; /* BRW_NEW_INTERPOLATION_MAP */ key.interpolation_mode = brw->interpolation_mode; /* _NEW_LIGHT | _NEW_PROGRAM */ key.do_twoside_color = ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) || ctx->VertexProgram._TwoSideEnabled); /* _NEW_POLYGON */ if (key.do_twoside_color) { /* If we're rendering to a FBO, we have to invert the polygon * face orientation, just as we invert the viewport in * sf_unit_create_from_key(). */ key.frontface_ccw = (ctx->Polygon.FrontFace == GL_CCW) != render_to_fbo; } if (!brw_search_cache(&brw->cache, BRW_SF_PROG, &key, sizeof(key), &brw->sf.prog_offset, &brw->sf.prog_data)) { compile_sf_prog( brw, &key ); } }
/* Calculate interpolants for triangle and line rasterization. */ static void upload_sf_prog( struct brw_context *brw ) { const struct brw_fragment_program *fs = brw->attribs.FragmentProgram; struct brw_sf_prog_key key; struct tgsi_parse_context parse; int i, done = 0; memset(&key, 0, sizeof(key)); /* Populate the key, noting state dependencies: */ /* CACHE_NEW_VS_PROG */ key.vp_output_count = brw->vs.prog_data->outputs_written; /* BRW_NEW_FS */ key.fp_input_count = brw->attribs.FragmentProgram->info.file_max[TGSI_FILE_INPUT] + 1; /* BRW_NEW_REDUCED_PRIMITIVE */ switch (brw->reduced_primitive) { case PIPE_PRIM_TRIANGLES: // if (key.attrs & (1<<VERT_RESULT_EDGE)) // key.primitive = SF_UNFILLED_TRIS; // else key.primitive = SF_TRIANGLES; break; case PIPE_PRIM_LINES: key.primitive = SF_LINES; break; case PIPE_PRIM_POINTS: key.primitive = SF_POINTS; break; } /* Scan fp inputs to figure out what interpolation modes are * required for each incoming vp output. There is an assumption * that the state tracker makes sure there is a 1:1 linkage between * these sets of attributes (XXX: position??) */ tgsi_parse_init( &parse, fs->program.tokens ); while( !done && !tgsi_parse_end_of_tokens( &parse ) ) { tgsi_parse_token( &parse ); switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT) { int first = parse.FullToken.FullDeclaration.DeclarationRange.First; int last = parse.FullToken.FullDeclaration.DeclarationRange.Last; int interp_mode = parse.FullToken.FullDeclaration.Declaration.Interpolate; //int semantic = parse.FullToken.FullDeclaration.Semantic.SemanticName; //int semantic_index = parse.FullToken.FullDeclaration.Semantic.SemanticIndex; debug_printf("fs input %d..%d interp mode %d\n", first, last, interp_mode); switch (interp_mode) { case TGSI_INTERPOLATE_CONSTANT: for (i = first; i <= last; i++) key.const_mask |= (1 << i); break; case TGSI_INTERPOLATE_LINEAR: for (i = first; i <= last; i++) key.linear_mask |= (1 << i); break; case TGSI_INTERPOLATE_PERSPECTIVE: for (i = first; i <= last; i++) key.persp_mask |= (1 << i); break; default: break; } /* Also need stuff for flat shading, twosided color. */ } break; default: done = 1; break; } } /* Hack: Adjust for position. Optimize away when not required (ie * for perspective interpolation). */ key.persp_mask <<= 1; key.linear_mask <<= 1; key.linear_mask |= 1; key.const_mask <<= 1; debug_printf("key.persp_mask: %x\n", key.persp_mask); debug_printf("key.linear_mask: %x\n", key.linear_mask); debug_printf("key.const_mask: %x\n", key.const_mask); // key.do_point_sprite = brw->attribs.Point->PointSprite; // key.SpriteOrigin = brw->attribs.Point->SpriteOrigin; // key.do_flat_shading = (brw->attribs.Raster->flatshade); // key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide); // if (key.do_twoside_color) // key.frontface_ccw = (brw->attribs.Polygon->FrontFace == GL_CCW); if (!search_cache(brw, &key)) compile_sf_prog( brw, &key ); }