static bool fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, unsigned index_offset) { struct fd3_context *fd3_ctx = fd3_context(ctx); struct fd3_emit emit = { .debug = &ctx->debug, .vtx = &ctx->vtx, .prog = &ctx->prog, .info = info, .key = { .color_two_side = ctx->rasterizer->light_twoside, .vclamp_color = ctx->rasterizer->clamp_vertex_color, .fclamp_color = ctx->rasterizer->clamp_fragment_color, .half_precision = ctx->in_blit && fd_half_precision(&ctx->batch->framebuffer), .has_per_samp = (fd3_ctx->fsaturate || fd3_ctx->vsaturate), .vsaturate_s = fd3_ctx->vsaturate_s, .vsaturate_t = fd3_ctx->vsaturate_t, .vsaturate_r = fd3_ctx->vsaturate_r, .fsaturate_s = fd3_ctx->fsaturate_s, .fsaturate_t = fd3_ctx->fsaturate_t, .fsaturate_r = fd3_ctx->fsaturate_r, }, .rasterflat = ctx->rasterizer->flatshade, .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable, .sprite_coord_mode = ctx->rasterizer->sprite_coord_mode, }; if (fd3_needs_manual_clipping(ctx->prog.vp, ctx->rasterizer)) emit.key.ucp_enables = ctx->rasterizer->clip_plane_enable; fixup_shader_state(ctx, &emit.key); unsigned dirty = ctx->dirty; /* do regular pass first, since that is more likely to fail compiling: */ if (!(fd3_emit_get_vp(&emit) && fd3_emit_get_fp(&emit))) return false; emit.key.binning_pass = false; emit.dirty = dirty; draw_impl(ctx, ctx->batch->draw, &emit, index_offset); /* and now binning pass: */ emit.key.binning_pass = true; emit.dirty = dirty & ~(FD_DIRTY_BLEND); emit.vp = NULL; /* we changed key so need to refetch vp */ emit.fp = NULL; draw_impl(ctx, ctx->batch->binning, &emit, index_offset); fd_context_all_clean(ctx); return true; }
static bool fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, unsigned index_offset) { struct fd6_context *fd6_ctx = fd6_context(ctx); struct fd6_emit emit = { .debug = &ctx->debug, .vtx = &ctx->vtx, .prog = &ctx->prog, .info = info, .key = { .color_two_side = ctx->rasterizer->light_twoside, .vclamp_color = ctx->rasterizer->clamp_vertex_color, .fclamp_color = ctx->rasterizer->clamp_fragment_color, .rasterflat = ctx->rasterizer->flatshade, .half_precision = ctx->in_blit && fd_half_precision(&ctx->batch->framebuffer), .ucp_enables = ctx->rasterizer->clip_plane_enable, .has_per_samp = (fd6_ctx->fsaturate || fd6_ctx->vsaturate || fd6_ctx->fastc_srgb || fd6_ctx->vastc_srgb), .vsaturate_s = fd6_ctx->vsaturate_s, .vsaturate_t = fd6_ctx->vsaturate_t, .vsaturate_r = fd6_ctx->vsaturate_r, .fsaturate_s = fd6_ctx->fsaturate_s, .fsaturate_t = fd6_ctx->fsaturate_t, .fsaturate_r = fd6_ctx->fsaturate_r, .vastc_srgb = fd6_ctx->vastc_srgb, .fastc_srgb = fd6_ctx->fastc_srgb, .vsamples = ctx->tex[PIPE_SHADER_VERTEX].samples, .fsamples = ctx->tex[PIPE_SHADER_FRAGMENT].samples, }, .rasterflat = ctx->rasterizer->flatshade, .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable, .sprite_coord_mode = ctx->rasterizer->sprite_coord_mode, }; fixup_shader_state(ctx, &emit.key); unsigned dirty = ctx->dirty; const struct ir3_shader_variant *vp = fd6_emit_get_vp(&emit); const struct ir3_shader_variant *fp = fd6_emit_get_fp(&emit); /* do regular pass first, since that is more likely to fail compiling: */ if (!vp || !fp) return false; ctx->stats.vs_regs += ir3_shader_halfregs(vp); ctx->stats.fs_regs += ir3_shader_halfregs(fp); /* figure out whether we need to disable LRZ write for binning * pass using draw pass's fp: */ emit.no_lrz_write = fp->writes_pos || fp->has_kill; emit.key.binning_pass = false; emit.dirty = dirty; draw_impl(ctx, ctx->batch->draw, &emit, index_offset); /* and now binning pass: */ emit.key.binning_pass = true; emit.dirty = dirty & ~(FD_DIRTY_BLEND); emit.vp = NULL; /* we changed key so need to refetch vp */ emit.fp = NULL; draw_impl(ctx, ctx->batch->binning, &emit, index_offset); if (emit.streamout_mask) { struct fd_ringbuffer *ring = ctx->batch->draw; for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { if (emit.streamout_mask & (1 << i)) { fd6_event_write(ctx->batch, ring, FLUSH_SO_0 + i, false); } } } fd_context_all_clean(ctx); return true; }