/** * Handle state changes. * Called just prior to drawing anything (pipe::draw_arrays(), etc). * * Hopefully this will remain quite simple, otherwise need to pull in * something like the state tracker mechanism. */ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) { struct llvmpipe_screen *lp_screen = llvmpipe_screen(llvmpipe->pipe.screen); /* Check for updated textures. */ if (llvmpipe->tex_timestamp != lp_screen->timestamp) { llvmpipe->tex_timestamp = lp_screen->timestamp; llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; } if (llvmpipe->dirty & (LP_NEW_FS | LP_NEW_VS)) compute_vertex_info(llvmpipe); if (llvmpipe->dirty & (LP_NEW_FS | LP_NEW_FRAMEBUFFER | LP_NEW_BLEND | LP_NEW_SCISSOR | LP_NEW_DEPTH_STENCIL_ALPHA | LP_NEW_RASTERIZER | LP_NEW_SAMPLER | LP_NEW_SAMPLER_VIEW | LP_NEW_OCCLUSION_QUERY)) llvmpipe_update_fs( llvmpipe ); if (llvmpipe->dirty & (LP_NEW_RASTERIZER)) { boolean discard = (llvmpipe->sample_mask & 1) == 0 || (llvmpipe->rasterizer ? llvmpipe->rasterizer->rasterizer_discard : FALSE); lp_setup_set_rasterizer_discard(llvmpipe->setup, discard); } if (llvmpipe->dirty & (LP_NEW_FS | LP_NEW_FRAMEBUFFER | LP_NEW_RASTERIZER)) llvmpipe_update_setup( llvmpipe ); if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color); if (llvmpipe->dirty & LP_NEW_SCISSOR) lp_setup_set_scissors(llvmpipe->setup, llvmpipe->scissors); if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) { lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value); lp_setup_set_stencil_ref_values(llvmpipe->setup, llvmpipe->stencil_ref.ref_value); } if (llvmpipe->dirty & LP_NEW_CONSTANTS) lp_setup_set_fs_constants(llvmpipe->setup, Elements(llvmpipe->constants[PIPE_SHADER_FRAGMENT]), llvmpipe->constants[PIPE_SHADER_FRAGMENT]); if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW)) lp_setup_set_fragment_sampler_views(llvmpipe->setup, llvmpipe->num_sampler_views[PIPE_SHADER_FRAGMENT], llvmpipe->sampler_views[PIPE_SHADER_FRAGMENT]); if (llvmpipe->dirty & (LP_NEW_SAMPLER)) lp_setup_set_fragment_sampler_state(llvmpipe->setup, llvmpipe->num_samplers[PIPE_SHADER_FRAGMENT], llvmpipe->samplers[PIPE_SHADER_FRAGMENT]); if (llvmpipe->dirty & LP_NEW_VIEWPORT) { /* * Update setup and fragment's view of the active viewport state. * * XXX TODO: It is possible to only loop over the active viewports * instead of all viewports (PIPE_MAX_VIEWPORTS). */ lp_setup_set_viewports(llvmpipe->setup, PIPE_MAX_VIEWPORTS, llvmpipe->viewports); } llvmpipe->dirty = 0; }
boolean lp_setup_update_state( struct lp_setup_context *setup, boolean update_scene ) { /* Some of the 'draw' pipeline stages may have changed some driver state. * Make sure we've processed those state changes before anything else. * * XXX this is the only place where llvmpipe_context is used in the * setup code. This may get refactored/changed... */ { struct llvmpipe_context *lp = llvmpipe_context(setup->pipe); if (lp->dirty) { llvmpipe_update_derived(lp); } if (lp->setup->dirty) { llvmpipe_update_setup(lp); } assert(setup->setup.variant); /* Will probably need to move this somewhere else, just need * to know about vertex shader point size attribute. */ setup->psize_slot = lp->psize_slot; setup->viewport_index_slot = lp->viewport_index_slot; setup->layer_slot = lp->layer_slot; setup->face_slot = lp->face_slot; assert(lp->dirty == 0); assert(lp->setup_variant.key.size == setup->setup.variant->key.size); assert(memcmp(&lp->setup_variant.key, &setup->setup.variant->key, setup->setup.variant->key.size) == 0); } if (update_scene && setup->state != SETUP_ACTIVE) { if (!set_scene_state( setup, SETUP_ACTIVE, __FUNCTION__ )) return FALSE; } /* Only call into update_scene_state() if we already have a * scene: */ if (update_scene && setup->scene) { assert(setup->state == SETUP_ACTIVE); if (try_update_scene_state(setup)) return TRUE; /* Update failed, try to restart the scene. * * Cannot call lp_setup_flush_and_restart() directly here * because of potential recursion. */ if (!set_scene_state(setup, SETUP_FLUSHED, __FUNCTION__)) return FALSE; if (!set_scene_state(setup, SETUP_ACTIVE, __FUNCTION__)) return FALSE; if (!setup->scene) return FALSE; return try_update_scene_state(setup); } return TRUE; }
/** * Handle state changes. * Called just prior to drawing anything (pipe::draw_arrays(), etc). * * Hopefully this will remain quite simple, otherwise need to pull in * something like the state tracker mechanism. */ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) { struct llvmpipe_screen *lp_screen = llvmpipe_screen(llvmpipe->pipe.screen); /* Check for updated textures. */ if (llvmpipe->tex_timestamp != lp_screen->timestamp) { llvmpipe->tex_timestamp = lp_screen->timestamp; llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; } if (llvmpipe->dirty & (LP_NEW_RASTERIZER | LP_NEW_FS | LP_NEW_VS)) compute_vertex_info( llvmpipe ); if (llvmpipe->dirty & (LP_NEW_FS | LP_NEW_FRAMEBUFFER | LP_NEW_BLEND | LP_NEW_SCISSOR | LP_NEW_DEPTH_STENCIL_ALPHA | LP_NEW_RASTERIZER | LP_NEW_SAMPLER | LP_NEW_SAMPLER_VIEW | LP_NEW_OCCLUSION_QUERY)) llvmpipe_update_fs( llvmpipe ); if (llvmpipe->dirty & (LP_NEW_FS | LP_NEW_RASTERIZER)) llvmpipe_update_setup( llvmpipe ); if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color); if (llvmpipe->dirty & LP_NEW_SCISSOR) lp_setup_set_scissors(llvmpipe->setup, llvmpipe->scissors); if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) { lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value); lp_setup_set_stencil_ref_values(llvmpipe->setup, llvmpipe->stencil_ref.ref_value); } if (llvmpipe->dirty & LP_NEW_CONSTANTS) lp_setup_set_fs_constants(llvmpipe->setup, Elements(llvmpipe->constants[PIPE_SHADER_FRAGMENT]), llvmpipe->constants[PIPE_SHADER_FRAGMENT]); if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW)) lp_setup_set_fragment_sampler_views(llvmpipe->setup, llvmpipe->num_sampler_views[PIPE_SHADER_FRAGMENT], llvmpipe->sampler_views[PIPE_SHADER_FRAGMENT]); if (llvmpipe->dirty & (LP_NEW_SAMPLER)) lp_setup_set_fragment_sampler_state(llvmpipe->setup, llvmpipe->num_samplers[PIPE_SHADER_FRAGMENT], llvmpipe->samplers[PIPE_SHADER_FRAGMENT]); llvmpipe->dirty = 0; }