void vg_validate_state(struct vg_context *ctx) { struct st_framebuffer *stfb = ctx->draw_buffer; vg_manager_validate_framebuffer(ctx); if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height)) ctx->state.dirty |= DEPTH_STENCIL_DIRTY; /* blend state depends on fb format and paint color */ if ((ctx->state.dirty & FRAMEBUFFER_DIRTY) || (ctx->state.dirty & PAINT_DIRTY)) ctx->state.dirty |= BLEND_DIRTY; renderer_validate(ctx->renderer, ctx->state.dirty, ctx->draw_buffer, &ctx->state.vg); ctx->state.dirty = 0; shader_set_masking(ctx->shader, ctx->state.vg.masking); shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode); shader_set_color_transform(ctx->shader, ctx->state.vg.color_transform); }
void vg_validate_state(struct vg_context *ctx) { vg_manager_validate_framebuffer(ctx); if ((ctx->state.dirty & BLEND_DIRTY)) { struct pipe_blend_state *blend = &ctx->state.g3d.blend; memset(blend, 0, sizeof(struct pipe_blend_state)); blend->rt[0].blend_enable = 1; blend->rt[0].colormask = PIPE_MASK_RGBA; switch (ctx->state.vg.blend_mode) { case VG_BLEND_SRC: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].blend_enable = 0; break; case VG_BLEND_SRC_OVER: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; break; case VG_BLEND_DST_OVER: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; break; case VG_BLEND_SRC_IN: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; break; case VG_BLEND_DST_IN: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; break; case VG_BLEND_MULTIPLY: case VG_BLEND_SCREEN: case VG_BLEND_DARKEN: case VG_BLEND_LIGHTEN: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].blend_enable = 0; break; case VG_BLEND_ADDITIVE: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; break; default: assert(!"not implemented blend mode"); } cso_set_blend(ctx->cso_context, &ctx->state.g3d.blend); } if ((ctx->state.dirty & RASTERIZER_DIRTY)) { struct pipe_rasterizer_state *raster = &ctx->state.g3d.rasterizer; memset(raster, 0, sizeof(struct pipe_rasterizer_state)); raster->gl_rasterization_rules = 1; cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer); } if ((ctx->state.dirty & VIEWPORT_DIRTY)) { struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; const VGint param_bytes = 8 * sizeof(VGfloat); VGfloat vs_consts[8] = { 2.f/fb->width, 2.f/fb->height, 1, 1, -1, -1, 0, 0 }; struct pipe_resource **cbuf = &ctx->vs_const_buffer; vg_set_viewport(ctx, VEGA_Y0_BOTTOM); pipe_resource_reference(cbuf, NULL); *cbuf = pipe_buffer_create(ctx->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, param_bytes); if (*cbuf) { st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, vs_consts); } ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf); } if ((ctx->state.dirty & VS_DIRTY)) { cso_set_vertex_shader_handle(ctx->cso_context, vg_plain_vs(ctx)); } /* must be last because it renders to the depth buffer*/ if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) { update_clip_state(ctx); cso_set_depth_stencil_alpha(ctx->cso_context, &ctx->state.g3d.dsa); } shader_set_masking(ctx->shader, ctx->state.vg.masking); shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode); ctx->state.dirty = NONE_DIRTY; }