示例#1
0
static void
svga_set_polygon_stipple(struct pipe_context *pipe,
                         const struct pipe_poly_stipple *stipple)
{
   struct svga_context *svga = svga_context(pipe);

   /* release old texture */
   pipe_resource_reference(&svga->polygon_stipple.texture, NULL);

   /* release old sampler view */
   if (svga->polygon_stipple.sampler_view) {
      pipe->sampler_view_destroy(pipe,
                                 &svga->polygon_stipple.sampler_view->base);
   }

   /* create new stipple texture */
   svga->polygon_stipple.texture =
      util_pstipple_create_stipple_texture(pipe, stipple->stipple);

   /* create new sampler view */
   svga->polygon_stipple.sampler_view =
      (struct svga_pipe_sampler_view *)
      util_pstipple_create_sampler_view(pipe,
                                        svga->polygon_stipple.texture);

   /* allocate sampler state, if first time */
   if (!svga->polygon_stipple.sampler) {
      svga->polygon_stipple.sampler = util_pstipple_create_sampler(pipe);
   }

   svga->dirty |= SVGA_NEW_STIPPLE;
}
示例#2
0
static void svga_destroy( struct pipe_context *pipe )
{
   struct svga_context *svga = svga_context( pipe );
   unsigned shader;

   svga_cleanup_framebuffer( svga );
   svga_cleanup_tss_binding( svga );

   svga_hwtnl_destroy( svga->hwtnl );

   svga_cleanup_vertex_state(svga);
   
   svga->swc->destroy(svga->swc);
   
   svga_destroy_swtnl( svga );

   u_upload_destroy( svga->upload_vb );
   u_upload_destroy( svga->upload_ib );

   util_bitmask_destroy( svga->vs_bm );
   util_bitmask_destroy( svga->fs_bm );

   for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader)
      pipe_resource_reference( &svga->curr.cb[shader], NULL );

   FREE( svga );
}
示例#3
0
static void *
svga_create_fs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_screen *svgascreen = svga_screen(pipe->screen);
   struct svga_fragment_shader *fs;

   fs = CALLOC_STRUCT(svga_fragment_shader);
   if (!fs)
      return NULL;

   fs->base.tokens = tgsi_dup_tokens(templ->tokens);

   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(fs->base.tokens, &fs->base.info);

   fs->base.id = svga->debug.shader_id++;
   fs->base.use_sm30 = svgascreen->use_ps30;
   
   if (SVGA_DEBUG & DEBUG_TGSI || 0) {
      debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
                   __FUNCTION__, fs->base.id,
                   fs->base.info.num_inputs, fs->base.info.num_outputs);
   }

   return fs;
}
示例#4
0
/**
 * Clear the given surface to the specified value.
 * No masking, no scissor (clear entire buffer).
 */
void
svga_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
	   double depth, unsigned stencil)
{
   struct svga_context *svga = svga_context( pipe );
   int ret;

   if (buffers & PIPE_CLEAR_COLOR)
      SVGA_DBG(DEBUG_DMA, "clear sid %p\n",
               svga_surface(svga->curr.framebuffer.cbufs[0])->handle);

   ret = try_clear( svga, buffers, rgba, depth, stencil );

   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
      /* Flush command buffer and retry:
       */
      svga_context_flush( svga, NULL );

      ret = try_clear( svga, buffers, rgba, depth, stencil );
   }

   /*
    * Mark target surfaces as dirty
    * TODO Mark only cleared surfaces.
    */
   svga_mark_surfaces_dirty(svga);

   assert (ret == PIPE_OK);
}
示例#5
0
static void *
svga_create_gs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_geometry_shader *gs = CALLOC_STRUCT(svga_geometry_shader);

   if (!gs)
      return NULL;

   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEGS);

   gs->base.tokens = tgsi_dup_tokens(templ->tokens);

   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(gs->base.tokens, &gs->base.info);

   gs->draw_shader = draw_create_geometry_shader(svga->swtnl.draw, templ);

   gs->base.id = svga->debug.shader_id++;

   gs->generic_outputs = svga_get_generic_outputs_mask(&gs->base.info);

   /* check for any stream output declarations */
   if (templ->stream_output.num_outputs) {
      gs->base.stream_output = svga_create_stream_output(svga, &gs->base,
                                                         &templ->stream_output);
   }

   SVGA_STATS_TIME_POP(svga_sws(svga));
   return gs;
}
static void svga_set_constant_buffer(struct pipe_context *pipe,
                                     uint shader, uint index,
                                     struct pipe_constant_buffer *cb)
{
   struct svga_context *svga = svga_context(pipe);
   struct pipe_resource *buf = cb ? cb->buffer : NULL;

   if (cb && cb->user_buffer) {
      buf = svga_user_buffer_create(pipe->screen,
                                    (void *) cb->user_buffer,
                                    cb->buffer_size,
                                    PIPE_BIND_CONSTANT_BUFFER);
   }

   assert(shader < PIPE_SHADER_TYPES);
   assert(index == 0);

   pipe_resource_reference( &svga->curr.cb[shader],
                          buf );

   if (shader == PIPE_SHADER_FRAGMENT)
      svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
   else
      svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;

   if (cb && cb->user_buffer) {
      pipe_resource_reference(&buf, NULL);
   }
}
示例#7
0
static void *
svga_create_vertex_elements_state(struct pipe_context *pipe,
                                  unsigned count,
                                  const struct pipe_vertex_element *attribs)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_velems_state *velems;

   assert(count <= PIPE_MAX_ATTRIBS);
   velems = (struct svga_velems_state *) MALLOC(sizeof(struct svga_velems_state));
   if (velems) {
      velems->count = count;
      memcpy(velems->velem, attribs, sizeof(*attribs) * count);

      velems->need_swvfetch = FALSE;
      velems->adjust_attrib_range = 0x0;
      velems->attrib_is_pure_int = 0x0;
      velems->adjust_attrib_w_1 = 0x0;
      velems->adjust_attrib_itof = 0x0;
      velems->adjust_attrib_utof = 0x0;
      velems->attrib_is_bgra = 0x0;
      velems->attrib_puint_to_snorm = 0x0;
      velems->attrib_puint_to_uscaled = 0x0;
      velems->attrib_puint_to_sscaled = 0x0;

      if (svga_have_vgpu10(svga)) {
         define_input_element_object(svga, velems);
      }
      else {
         translate_vertex_decls(svga, velems);
      }
   }
   return velems;
}
/**
 * \brief Clear render target pipe callback
 *
 * \param pipe[in]  The pipe context
 * \param dst[in]  The surface to clear
 * \param color[in]  Clear color
 * \param dstx[in]  Clear region left
 * \param dsty[in]  Clear region top
 * \param width[in]  Clear region width
 * \param height[in]  Clear region height
 * \param render_condition_enabled[in]  Whether to use conditional rendering
 * to clear (if elsewhere enabled).
 */
static void
svga_clear_render_target(struct pipe_context *pipe,
                         struct pipe_surface *dst,
                         const union pipe_color_union *color,
                         unsigned dstx, unsigned dsty,
                         unsigned width, unsigned height,
                         bool render_condition_enabled)
{
    struct svga_context *svga = svga_context( pipe );

    svga_toggle_render_condition(svga, render_condition_enabled, FALSE);
    if (!svga_have_vgpu10(svga) || dstx != 0 || dsty != 0 ||
        width != dst->width || height != dst->height) {
       svga_blitter_clear_render_target(svga, dst, color, dstx, dsty, width,
                                        height);
    } else {
       enum pipe_error ret;
       
       ret = svga_try_clear_render_target(svga, dst, color);
       if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
          svga_context_flush( svga, NULL );
          ret = svga_try_clear_render_target(svga, dst, color);
       }
       
       assert (ret == PIPE_OK);
    }
    svga_toggle_render_condition(svga, render_condition_enabled, TRUE);
}
示例#9
0
static void
svga_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_velems_state *velems = (struct svga_velems_state *) state;

   if (svga_have_vgpu10(svga)) {
      enum pipe_error ret;

      svga_hwtnl_flush_retry(svga);

      ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, velems->id);
      if (ret != PIPE_OK) {
         svga_context_flush(svga, NULL);
         ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, velems->id);
         assert(ret == PIPE_OK);
      }

      if (velems->id == svga->state.hw_draw.layout_id)
         svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID;

      util_bitmask_clear(svga->input_element_object_id_bm, velems->id);
      velems->id = SVGA3D_INVALID_ID;
   }

   FREE(velems);
}
示例#10
0
static void svga_set_index_buffer(struct pipe_context *pipe,
                                  const struct pipe_index_buffer *ib)
{
   struct svga_context *svga = svga_context(pipe);

   util_set_index_buffer(&svga->curr.ib, ib);
}
static void
svga_clear_depth_stencil(struct pipe_context *pipe,
                         struct pipe_surface *dst,
                         unsigned clear_flags,
                         double depth,
                         unsigned stencil,
                         unsigned dstx, unsigned dsty,
                         unsigned width, unsigned height,
                         bool render_condition_enabled)
{
    struct svga_context *svga = svga_context( pipe );

    svga_toggle_render_condition(svga, render_condition_enabled, FALSE);

    /* Use software fallback */
    begin_blit(svga);
    util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer);
    util_blitter_clear_depth_stencil(svga->blitter,
                                     dst, clear_flags,
                                     depth, stencil,
                                     dstx, dsty,
                                     width, height);

    svga_toggle_render_condition(svga, render_condition_enabled, TRUE);
}
示例#12
0
/**
 * Clear the given surface to the specified value.
 * No masking, no scissor (clear entire buffer).
 */
void
svga_clear(struct pipe_context *pipe, unsigned buffers,
           const union pipe_color_union *color,
	   double depth, unsigned stencil)
{
   struct svga_context *svga = svga_context( pipe );
   enum pipe_error ret;

   if (buffers & PIPE_CLEAR_COLOR)
      SVGA_DBG(DEBUG_DMA, "clear sid %p\n",
               svga_surface(svga->curr.framebuffer.cbufs[0])->handle);

   /* flush any queued prims (don't want them to appear after the clear!) */
   svga_hwtnl_flush_retry(svga);

   ret = try_clear( svga, buffers, color, depth, stencil );

   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
      /* Flush command buffer and retry:
       */
      svga_context_flush( svga, NULL );

      ret = try_clear( svga, buffers, color, depth, stencil );
   }

   /*
    * Mark target surfaces as dirty
    * TODO Mark only cleared surfaces.
    */
   svga_mark_surfaces_dirty(svga);

   assert (ret == PIPE_OK);
}
示例#13
0
static void
svga_texture_transfer_destroy(struct pipe_context *pipe,
                              struct pipe_transfer *transfer)
{
    struct svga_context *svga = svga_context(pipe);
    struct svga_texture *tex = svga_texture(transfer->resource);
    struct svga_screen *ss = svga_screen(pipe->screen);
    struct svga_winsys_screen *sws = ss->sws;
    struct svga_transfer *st = svga_transfer(transfer);

    if (st->base.usage & PIPE_TRANSFER_WRITE) {
        SVGA3dSurfaceDMAFlags flags;

        memset(&flags, 0, sizeof flags);
        if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
            flags.discard = TRUE;
        }
        if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
            flags.unsynchronized = TRUE;
        }

        svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
        ss->texture_timestamp++;
        tex->view_age[transfer->level] = ++(tex->age);
        if (transfer->resource->target == PIPE_TEXTURE_CUBE)
            tex->defined[transfer->box.z][transfer->level] = TRUE;
        else
            tex->defined[0][transfer->level] = TRUE;
    }

    pipe_resource_reference(&st->base.resource, NULL);
    FREE(st->swbuf);
    sws->buffer_destroy(sws, st->hwbuf);
    FREE(st);
}
示例#14
0
static void *
svga_create_fs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_fragment_shader *fs;

   fs = CALLOC_STRUCT(svga_fragment_shader);
   if (!fs)
      return NULL;

   fs->base.tokens = tgsi_dup_tokens(templ->tokens);

   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(fs->base.tokens, &fs->base.info);

   fs->base.id = svga->debug.shader_id++;
   
   fs->generic_inputs = svga_get_generic_inputs_mask(&fs->base.info);

   svga_remap_generics(fs->generic_inputs, fs->generic_remap_table);

   fs->draw_shader = draw_create_fragment_shader(svga->swtnl.draw, templ);

   if (SVGA_DEBUG & DEBUG_TGSI || 0) {
      debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
                   __FUNCTION__, fs->base.id,
                   fs->base.info.num_inputs, fs->base.info.num_outputs);
   }

   return fs;
}
示例#15
0
static void svga_blit(struct pipe_context *pipe,
                      const struct pipe_blit_info *blit_info)
{
   struct svga_context *svga = svga_context(pipe);
   struct pipe_blit_info info = *blit_info;

   if (info.src.resource->nr_samples > 1 &&
       info.dst.resource->nr_samples <= 1 &&
       !util_format_is_depth_or_stencil(info.src.resource->format) &&
       !util_format_is_pure_integer(info.src.resource->format)) {
      debug_printf("svga: color resolve unimplemented\n");
      return;
   }

   if (util_try_blit_via_copy_region(pipe, &info)) {
      return; /* done */
   }

   if (info.mask & PIPE_MASK_S) {
      debug_printf("svga: cannot blit stencil, skipping\n");
      info.mask &= ~PIPE_MASK_S;
   }

   if (!util_blitter_is_blit_supported(svga->blitter, &info)) {
      debug_printf("svga: blit unsupported %s -> %s\n",
                   util_format_short_name(info.src.resource->format),
                   util_format_short_name(info.dst.resource->format));
      return;
   }

   /* XXX turn off occlusion and streamout queries */

   util_blitter_save_vertex_buffers(svga->blitter,
                                    svga->curr.num_vertex_buffers,
                                    svga->curr.vb);
   util_blitter_save_vertex_elements(svga->blitter, (void*)svga->curr.velems);
   util_blitter_save_vertex_shader(svga->blitter, svga->curr.vs);
   /*util_blitter_save_geometry_shader(svga->blitter, svga->curr.gs);*/
   /*util_blitter_save_so_targets(svga->blitter, svga->num_so_targets,
                     (struct pipe_stream_output_target**)svga->so_targets);*/
   util_blitter_save_rasterizer(svga->blitter, (void*)svga->curr.rast);
   util_blitter_save_viewport(svga->blitter, &svga->curr.viewport);
   util_blitter_save_scissor(svga->blitter, &svga->curr.scissor);
   util_blitter_save_fragment_shader(svga->blitter, svga->curr.fs);
   util_blitter_save_blend(svga->blitter, (void*)svga->curr.blend);
   util_blitter_save_depth_stencil_alpha(svga->blitter,
                                         (void*)svga->curr.depth);
   util_blitter_save_stencil_ref(svga->blitter, &svga->curr.stencil_ref);
   /*util_blitter_save_sample_mask(svga->blitter, svga->sample_mask);*/
   util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer);
   util_blitter_save_fragment_sampler_states(svga->blitter,
                     svga->curr.num_samplers,
                     (void**)svga->curr.sampler);
   util_blitter_save_fragment_sampler_views(svga->blitter,
                     svga->curr.num_sampler_views,
                     svga->curr.sampler_views);
   /*util_blitter_save_render_condition(svga->blitter, svga->render_cond_query,
                                      svga->render_cond_mode);*/
   util_blitter_blit(svga->blitter, &info);
}
示例#16
0
static struct pipe_stream_output_target *
svga_create_stream_output_target(struct pipe_context *pipe,
                                 struct pipe_resource *buffer,
                                 unsigned buffer_offset,
                                 unsigned buffer_size)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_stream_output_target *sot;

   SVGA_DBG(DEBUG_STREAMOUT, "%s offset=%d size=%d\n", __FUNCTION__,
            buffer_offset, buffer_size);

   assert(svga_have_vgpu10(svga));
   (void) svga;

   sot = CALLOC_STRUCT(svga_stream_output_target);
   if (!sot)
      return NULL;

   pipe_reference_init(&sot->base.reference, 1);
   pipe_resource_reference(&sot->base.buffer, buffer);
   sot->base.context = pipe;
   sot->base.buffer = buffer;
   sot->base.buffer_offset = buffer_offset;
   sot->base.buffer_size = buffer_size;

   return &sot->base;
}
示例#17
0
static void svga_delete_vs_state(struct pipe_context *pipe, void *shader)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
   struct svga_shader_result *result, *tmp;
   enum pipe_error ret;

   svga_hwtnl_flush_retry( svga );

   draw_delete_vertex_shader(svga->swtnl.draw, vs->draw_shader);
   
   for (result = vs->base.results; result; result = tmp ) {
      tmp = result->next;

      ret = SVGA3D_DestroyShader(svga->swc, 
                                 result->id,
                                 SVGA3D_SHADERTYPE_VS );
      if(ret != PIPE_OK) {
         svga_context_flush(svga, NULL);
         ret = SVGA3D_DestroyShader(svga->swc, 
                                    result->id,
                                    SVGA3D_SHADERTYPE_VS );
         assert(ret == PIPE_OK);
      }

      svga_destroy_shader_result( result );
   }

   FREE((void *)vs->base.tokens);
   FREE(vs);
}
static void svga_set_vertex_buffers(struct pipe_context *pipe,
                                    unsigned count,
                                    const struct pipe_vertex_buffer *buffers)
{
   struct svga_context *svga = svga_context(pipe);
   unsigned i;
   boolean any_user_buffer = FALSE;

   /* Check for no change */
   if (count == svga->curr.num_vertex_buffers &&
       memcmp(svga->curr.vb, buffers, count * sizeof buffers[0]) == 0)
      return;

   /* Adjust refcounts */
   for (i = 0; i < count; i++) {
      pipe_resource_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
      if (svga_buffer_is_user_buffer(buffers[i].buffer))
         any_user_buffer = TRUE;
   }

   for ( ; i < svga->curr.num_vertex_buffers; i++)
      pipe_resource_reference(&svga->curr.vb[i].buffer, NULL);

   /* Copy remaining data */
   memcpy(svga->curr.vb, buffers, count * sizeof buffers[0]);
   svga->curr.num_vertex_buffers = count;
   svga->curr.any_user_vertex_buffers = any_user_buffer;

   svga->dirty |= SVGA_NEW_VBUFFER;
}
示例#19
0
static void svga_end_query(struct pipe_context *pipe, 
                           struct pipe_query *q)
{
   struct svga_context *svga = svga_context( pipe );
   struct svga_query *sq = svga_query( q );
   enum pipe_error ret;

   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
   assert(svga->sq == sq);

   svga_hwtnl_flush_retry(svga);
   
   /* Set to PENDING before sending EndQuery. */
   sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;

   ret = SVGA3D_EndQuery( svga->swc, sq->type, sq->hwbuf);
   if(ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_EndQuery( svga->swc, sq->type, sq->hwbuf);
      assert(ret == PIPE_OK);
   }
   
   /* TODO: Delay flushing. We don't really need to flush here, just ensure 
    * that there is one flush before svga_get_query_result attempts to get the
    * result */
   svga_context_flush(svga, NULL);

   svga->sq = NULL;
}
static void svga_bind_depth_stencil_state(struct pipe_context *pipe,
                                          void *depth_stencil)
{
   struct svga_context *svga = svga_context(pipe);

   svga->curr.depth = (const struct svga_depth_stencil_state *)depth_stencil;
   svga->dirty |= SVGA_NEW_DEPTH_STENCIL;
}
示例#21
0
static void svga_set_scissor_state( struct pipe_context *pipe,
                                 const struct pipe_scissor_state *scissor )
{
   struct svga_context *svga = svga_context(pipe);

   memcpy( &svga->curr.scissor, scissor, sizeof(*scissor) );
   svga->dirty |= SVGA_NEW_SCISSOR;
}
示例#22
0
static void svga_bind_blend_state(struct pipe_context *pipe,
                                  void *blend)
{
   struct svga_context *svga = svga_context(pipe);

   svga->curr.blend = (struct svga_blend_state*)blend;
   svga->dirty |= SVGA_NEW_BLEND;
}
示例#23
0
static void svga_bind_vs_state(struct pipe_context *pipe, void *shader)
{
   struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
   struct svga_context *svga = svga_context(pipe);

   svga->curr.vs = vs;
   svga->dirty |= SVGA_NEW_VS;
}
示例#24
0
static void
svga_bind_gs_state(struct pipe_context *pipe, void *shader)
{
   struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader;
   struct svga_context *svga = svga_context(pipe);

   svga->curr.user_gs = gs;
   svga->dirty |= SVGA_NEW_GS;
}
static void svga_set_stencil_ref( struct pipe_context *pipe,
                                  const struct pipe_stencil_ref *stencil_ref )
{
   struct svga_context *svga = svga_context(pipe);

   svga->curr.stencil_ref = *stencil_ref;

   svga->dirty |= SVGA_NEW_STENCIL_REF;
}
示例#26
0
/**
 * svga_fence_server_sync
 *
 * This function imports a fence from another process/device into the current
 * software context so that SVGA can synchronize with it.
 */
static void
svga_fence_server_sync(struct pipe_context *pipe,
                       struct pipe_fence_handle *fence)
{
   struct svga_winsys_screen *sws = svga_winsys_screen(pipe->screen);
   struct svga_context *svga = svga_context(pipe);

   sws->fence_server_sync(sws, &svga->swc->imported_fence_fd, fence);
}
示例#27
0
static void
svga_bind_fs_state(struct pipe_context *pipe, void *shader)
{
   struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
   struct svga_context *svga = svga_context(pipe);

   svga->curr.fs = fs;
   svga->dirty |= SVGA_NEW_FS;
}
示例#28
0
static void svga_set_clip_state( struct pipe_context *pipe,
                                 const struct pipe_clip_state *clip )
{
   struct svga_context *svga = svga_context(pipe);

   svga->curr.clip = *clip; /* struct copy */

   svga->dirty |= SVGA_NEW_CLIP;
}
示例#29
0
static void svga_set_blend_color( struct pipe_context *pipe,
                                  const struct pipe_blend_color *blend_color )
{
   struct svga_context *svga = svga_context(pipe);

   svga->curr.blend_color = *blend_color;

   svga->dirty |= SVGA_NEW_BLEND;
}
static void svga_bind_vertex_elements_state(struct pipe_context *pipe,
                                            void *velems)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_velems_state *svga_velems = (struct svga_velems_state *) velems;

   svga->curr.velems = svga_velems;
   svga->dirty |= SVGA_NEW_VELEMENT;
}