/**
 * 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_BLEND |
                          LP_NEW_SCISSOR |
                          LP_NEW_DEPTH_STENCIL_ALPHA |
                          LP_NEW_RASTERIZER |
                          LP_NEW_SAMPLER |
                          LP_NEW_SAMPLER_VIEW |
                          LP_NEW_QUERY))
      llvmpipe_update_fs( 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_scissor(llvmpipe->setup, &llvmpipe->scissor);

   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, 
                                llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);

   if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
      lp_setup_set_fragment_sampler_views(llvmpipe->setup,
                                          llvmpipe->num_fragment_sampler_views,
                                          llvmpipe->fragment_sampler_views);

   llvmpipe->dirty = 0;
}
Exemple #2
0
/**
 * 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;
}