gallium: allow setting of the internal stream output offset
[mesa.git] / src / gallium / auxiliary / util / u_gen_mipmap.c
index 5bf0f53d084ad13eed8788cdcb7bb030a327c63f..dad3ad2ec1d18d88dc2321e20e6af0c64e09e88f 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
  * All Rights Reserved.
  * Copyright 2008  VMware, Inc.  All rights reserved.
  *
@@ -19,7 +19,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -59,15 +59,17 @@ struct gen_mipmap_state
    struct pipe_context *pipe;
    struct cso_context *cso;
 
-   struct pipe_blend_state blend;
-   struct pipe_depth_stencil_alpha_state depthstencil;
+   struct pipe_blend_state blend_keep_color, blend_write_color;
+   struct pipe_depth_stencil_alpha_state dsa_keep_depth, dsa_write_depth;
    struct pipe_rasterizer_state rasterizer;
    struct pipe_sampler_state sampler;
-   struct pipe_clip_state clip;
    struct pipe_vertex_element velem[2];
 
    void *vs;
-   void *fs1d, *fs2d, *fs3d, *fsCube, *fs1da, *fs2da;
+
+   /** Not all are used, but simplifies code */
+   void *fs_color[TGSI_TEXTURE_COUNT];
+   void *fs_depth[TGSI_TEXTURE_COUNT];
 
    struct pipe_resource *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -1109,17 +1111,14 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
       struct pipe_transfer *srcTrans, *dstTrans;
       void *srcMap, *dstMap;
 
-      srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
-                                   PIPE_TRANSFER_READ, 0, 0,
-                                   u_minify(pt->width0, srcLevel),
-                                   u_minify(pt->height0, srcLevel));
-      dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
-                                   PIPE_TRANSFER_WRITE, 0, 0,
-                                   u_minify(pt->width0, dstLevel),
-                                   u_minify(pt->height0, dstLevel));
-
-      srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
-      dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
+      srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer,
+                                 PIPE_TRANSFER_READ, 0, 0,
+                                 u_minify(pt->width0, srcLevel),
+                                 u_minify(pt->height0, srcLevel), &srcTrans);
+      dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer,
+                                 PIPE_TRANSFER_WRITE, 0, 0,
+                                 u_minify(pt->width0, dstLevel),
+                                 u_minify(pt->height0, dstLevel), &dstTrans);
 
       reduce_1d(pt->format,
                 srcTrans->box.width, srcMap,
@@ -1127,9 +1126,6 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
 
       pipe->transfer_unmap(pipe, srcTrans);
       pipe->transfer_unmap(pipe, dstTrans);
-
-      pipe->transfer_destroy(pipe, srcTrans);
-      pipe->transfer_destroy(pipe, dstTrans);
    }
 }
 
@@ -1150,17 +1146,14 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
       struct pipe_transfer *srcTrans, *dstTrans;
       ubyte *srcMap, *dstMap;
 
-      srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
-                                   PIPE_TRANSFER_READ, 0, 0,
-                                   u_minify(pt->width0, srcLevel),
-                                   u_minify(pt->height0, srcLevel));
-      dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
-                                   PIPE_TRANSFER_WRITE, 0, 0,
-                                   u_minify(pt->width0, dstLevel),
-                                   u_minify(pt->height0, dstLevel));
-
-      srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
-      dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
+      srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer,
+                                 PIPE_TRANSFER_READ, 0, 0,
+                                 u_minify(pt->width0, srcLevel),
+                                 u_minify(pt->height0, srcLevel), &srcTrans);
+      dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer,
+                                 PIPE_TRANSFER_WRITE, 0, 0,
+                                 u_minify(pt->width0, dstLevel),
+                                 u_minify(pt->height0, dstLevel), &dstTrans);
 
       reduce_2d(pt->format,
                 srcTrans->box.width, srcTrans->box.height,
@@ -1170,9 +1163,6 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
 
       pipe->transfer_unmap(pipe, srcTrans);
       pipe->transfer_unmap(pipe, dstTrans);
-
-      pipe->transfer_destroy(pipe, srcTrans);
-      pipe->transfer_destroy(pipe, dstTrans);
    }
 }
 
@@ -1205,15 +1195,12 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
       dst_box.height = u_minify(pt->height0, dstLevel);
       dst_box.depth = u_minify(pt->depth0, dstLevel);
 
-      srcTrans = pipe->get_transfer(pipe, pt, srcLevel,
-                                    PIPE_TRANSFER_READ,
-                                    &src_box);
-      dstTrans = pipe->get_transfer(pipe, pt, dstLevel,
-                                    PIPE_TRANSFER_WRITE,
-                                    &dst_box);
-
-      srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
-      dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
+      srcMap = pipe->transfer_map(pipe, pt, srcLevel,
+                                  PIPE_TRANSFER_READ,
+                                  &src_box, &srcTrans);
+      dstMap = pipe->transfer_map(pipe, pt, dstLevel,
+                                  PIPE_TRANSFER_WRITE,
+                                  &dst_box, &dstTrans);
 
       reduce_3d(pt->format,
                 srcTrans->box.width, srcTrans->box.height, srcTrans->box.depth,
@@ -1223,9 +1210,6 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
 
       pipe->transfer_unmap(pipe, srcTrans);
       pipe->transfer_unmap(pipe, dstTrans);
-
-      pipe->transfer_destroy(pipe, srcTrans);
-      pipe->transfer_destroy(pipe, dstTrans);
    }
 }
 
@@ -1273,16 +1257,23 @@ util_create_gen_mipmap(struct pipe_context *pipe,
    ctx->cso = cso;
 
    /* disabled blending/masking */
-   memset(&ctx->blend, 0, sizeof(ctx->blend));
-   ctx->blend.rt[0].colormask = PIPE_MASK_RGBA;
+   memset(&ctx->blend_keep_color, 0, sizeof(ctx->blend_keep_color));
+   memset(&ctx->blend_write_color, 0, sizeof(ctx->blend_write_color));
+   ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA;
 
    /* no-op depth/stencil/alpha */
-   memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
+   memset(&ctx->dsa_keep_depth, 0, sizeof(ctx->dsa_keep_depth));
+   memset(&ctx->dsa_write_depth, 0, sizeof(ctx->dsa_write_depth));
+   ctx->dsa_write_depth.depth.enabled = 1;
+   ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS;
+   ctx->dsa_write_depth.depth.writemask = 1;
 
    /* rasterizer */
    memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
    ctx->rasterizer.cull_face = PIPE_FACE_NONE;
-   ctx->rasterizer.gl_rasterization_rules = 1;
+   ctx->rasterizer.half_pixel_center = 1;
+   ctx->rasterizer.bottom_edge_rule = 1;
+   ctx->rasterizer.depth_clip = 1;
 
    /* sampler state */
    memset(&ctx->sampler, 0, sizeof(ctx->sampler));
@@ -1297,38 +1288,10 @@ util_create_gen_mipmap(struct pipe_context *pipe,
    for (i = 0; i < 2; i++) {
       ctx->velem[i].src_offset = i * 4 * sizeof(float);
       ctx->velem[i].instance_divisor = 0;
-      ctx->velem[i].vertex_buffer_index = 0;
+      ctx->velem[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso);
       ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
    }
 
-   /* vertex shader - still needed to specify mapping from fragment
-    * shader input semantics to vertex elements 
-    */
-   {
-      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
-                                      TGSI_SEMANTIC_GENERIC };
-      const uint semantic_indexes[] = { 0, 0 };
-      ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
-                                                    semantic_indexes);
-   }
-
-   /* fragment shader */
-   ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D,
-                                             TGSI_INTERPOLATE_LINEAR);
-   ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
-                                             TGSI_INTERPOLATE_LINEAR);
-   ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D,
-                                               TGSI_INTERPOLATE_LINEAR);
-   ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE,
-                                               TGSI_INTERPOLATE_LINEAR);
-   if (pipe->screen->get_param(pipe->screen, PIPE_CAP_ARRAY_TEXTURES)) {
-      ctx->fs1da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D_ARRAY,
-                                                 TGSI_INTERPOLATE_LINEAR);
-      ctx->fs2da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D_ARRAY,
-                                                 TGSI_INTERPOLATE_LINEAR);
-   }
-
-
    /* vertex data that doesn't change */
    for (i = 0; i < 4; i++) {
       ctx->vertices[i][0][2] = 0.0f; /* z */
@@ -1342,6 +1305,55 @@ util_create_gen_mipmap(struct pipe_context *pipe,
 }
 
 
+/**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct gen_mipmap_state *ctx, uint type,
+                    boolean output_depth)
+{
+   if (output_depth) {
+      if (!ctx->fs_depth[type])
+         ctx->fs_depth[type] =
+            util_make_fragment_tex_shader_writedepth(ctx->pipe, type,
+                                                     TGSI_INTERPOLATE_LINEAR);
+
+      cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[type]);
+   }
+   else {
+      if (!ctx->fs_color[type])
+         ctx->fs_color[type] =
+            util_make_fragment_tex_shader(ctx->pipe, type,
+                                          TGSI_INTERPOLATE_LINEAR);
+
+      cso_set_fragment_shader_handle(ctx->cso, ctx->fs_color[type]);
+   }
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct gen_mipmap_state *ctx)
+{
+   /* vertex shader - still required to provide the linkage between
+    * fragment shader input semantics and vertex_element/buffers.
+    */
+   if (!ctx->vs)
+   {
+      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+                                      TGSI_SEMANTIC_GENERIC };
+      const uint semantic_indexes[] = { 0, 0 };
+      ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+                                                    semantic_names,
+                                                    semantic_indexes);
+   }
+
+   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
 /**
  * Get next "slot" of vertex space in the vertex buffer.
  * We're allocating one large vertex buffer and using it piece by piece.
@@ -1351,8 +1363,10 @@ get_next_slot(struct gen_mipmap_state *ctx)
 {
    const unsigned max_slots = 4096 / sizeof ctx->vertices;
 
-   if (ctx->vbuf_slot >= max_slots) 
-      util_gen_mipmap_flush( ctx );
+   if (ctx->vbuf_slot >= max_slots) {
+      pipe_resource_reference(&ctx->vbuf, NULL);
+      ctx->vbuf_slot = 0;
+   }
 
    if (!ctx->vbuf) {
       ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
@@ -1395,7 +1409,8 @@ set_vertex_data(struct gen_mipmap_state *ctx,
       };
 
       util_map_texcoords2d_onto_cubemap(layer, &st[0][0], 2,
-                                        &ctx->vertices[0][1][0], 8);
+                                        &ctx->vertices[0][1][0], 8,
+                                        FALSE);
    }
    else if (tex_target == PIPE_TEXTURE_1D_ARRAY) {
       /* 1D texture array  */
@@ -1450,16 +1465,18 @@ void
 util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
+   unsigned i;
+
+   for (i = 0; i < Elements(ctx->fs_color); i++)
+      if (ctx->fs_color[i])
+         pipe->delete_fs_state(pipe, ctx->fs_color[i]);
 
-   if (ctx->fs2da)
-      pipe->delete_fs_state(pipe, ctx->fs2da);
-   if (ctx->fs1da)
-      pipe->delete_fs_state(pipe, ctx->fs1da);
-   pipe->delete_fs_state(pipe, ctx->fsCube);
-   pipe->delete_fs_state(pipe, ctx->fs3d);
-   pipe->delete_fs_state(pipe, ctx->fs2d);
-   pipe->delete_fs_state(pipe, ctx->fs1d);
-   pipe->delete_vs_state(pipe, ctx->vs);
+   for (i = 0; i < Elements(ctx->fs_depth); i++)
+      if (ctx->fs_depth[i])
+         pipe->delete_fs_state(pipe, ctx->fs_depth[i]);
+
+   if (ctx->vs)
+      pipe->delete_vs_state(pipe, ctx->vs);
 
    pipe_resource_reference(&ctx->vbuf, NULL);
 
@@ -1467,17 +1484,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
 }
 
 
-
-/* Release vertex buffer at end of frame to avoid synchronous
- * rendering.
- */
-void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
-{
-   pipe_resource_reference(&ctx->vbuf, NULL);
-   ctx->vbuf_slot = 0;
-} 
-
-
 /**
  * Generate mipmap images.  It's assumed all needed texture memory is
  * already allocated.
@@ -1498,9 +1504,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    struct pipe_screen *screen = pipe->screen;
    struct pipe_framebuffer_state fb;
    struct pipe_resource *pt = psv->texture;
-   void *fs;
    uint dstLevel;
    uint offset;
+   uint type;
+   boolean is_depth = util_format_is_depth_or_stencil(psv->format);
 
    /* The texture object should have room for the levels which we're
     * about to generate.
@@ -1515,31 +1522,33 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
 
    switch (pt->target) {
    case PIPE_TEXTURE_1D:
-      fs = ctx->fs1d;
+      type = TGSI_TEXTURE_1D;
       break;
    case PIPE_TEXTURE_2D:
-      fs = ctx->fs2d;
+      type = TGSI_TEXTURE_2D;
       break;
    case PIPE_TEXTURE_3D:
-      fs = ctx->fs3d;
+      type = TGSI_TEXTURE_3D;
       break;
    case PIPE_TEXTURE_CUBE:
-      fs = ctx->fsCube;
+      type = TGSI_TEXTURE_CUBE;
       break;
    case PIPE_TEXTURE_1D_ARRAY:
-      fs = ctx->fs1da;
+      type = TGSI_TEXTURE_1D_ARRAY;
       break;
    case PIPE_TEXTURE_2D_ARRAY:
-      fs = ctx->fs2da;
+      type = TGSI_TEXTURE_2D_ARRAY;
       break;
    default:
       assert(0);
-      fs = ctx->fs2d;
+      type = TGSI_TEXTURE_2D;
    }
 
    /* check if we can render in the texture's format */
    if (!screen->is_format_supported(screen, psv->format, pt->target,
-                                    pt->nr_samples, PIPE_BIND_RENDER_TARGET)) {
+                                    pt->nr_samples,
+                                    is_depth ? PIPE_BIND_DEPTH_STENCIL :
+                                               PIPE_BIND_RENDER_TARGET)) {
       fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
       return;
    }
@@ -1548,37 +1557,41 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_save_blend(ctx->cso);
    cso_save_depth_stencil_alpha(ctx->cso);
    cso_save_rasterizer(ctx->cso);
-   cso_save_samplers(ctx->cso);
-   cso_save_fragment_sampler_views(ctx->cso);
+   cso_save_sample_mask(ctx->cso);
+   cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
+   cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
+   cso_save_stream_outputs(ctx->cso);
    cso_save_framebuffer(ctx->cso);
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
+   cso_save_geometry_shader(ctx->cso);
    cso_save_viewport(ctx->cso);
-   cso_save_clip(ctx->cso);
    cso_save_vertex_elements(ctx->cso);
+   cso_save_aux_vertex_buffer_slot(ctx->cso);
+   cso_save_render_condition(ctx->cso);
 
    /* bind our state */
-   cso_set_blend(ctx->cso, &ctx->blend);
-   cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
+   cso_set_blend(ctx->cso, is_depth ? &ctx->blend_keep_color :
+                                      &ctx->blend_write_color);
+   cso_set_depth_stencil_alpha(ctx->cso, is_depth ? &ctx->dsa_write_depth :
+                                                    &ctx->dsa_keep_depth);
    cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
-   cso_set_clip(ctx->cso, &ctx->clip);
+   cso_set_sample_mask(ctx->cso, ~0);
    cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
+   cso_set_stream_outputs(ctx->cso, 0, NULL, NULL);
+   cso_set_render_condition(ctx->cso, NULL, FALSE, 0);
 
-   cso_set_fragment_shader_handle(ctx->cso, fs);
-   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+   set_fragment_shader(ctx, type, is_depth);
+   set_vertex_shader(ctx);
+   cso_set_geometry_shader_handle(ctx->cso, NULL);
 
    /* init framebuffer state */
    memset(&fb, 0, sizeof(fb));
-   fb.nr_cbufs = 1;
 
    /* set min/mag to same filter for faster sw speed */
    ctx->sampler.mag_img_filter = filter;
    ctx->sampler.min_img_filter = filter;
 
-   /*
-    * XXX for small mipmap levels, it may be faster to use the software
-    * fallback path...
-    */
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
       struct pipe_viewport_state vp;
@@ -1606,8 +1619,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
         } else
             layer = face;
 
-         memset(&surf_templ, 0, sizeof(surf_templ));
-         u_surface_default_template(&surf_templ, pt, PIPE_BIND_RENDER_TARGET);
+         u_surface_default_template(&surf_templ, pt);
          surf_templ.u.tex.level = dstLevel;
          surf_templ.u.tex.first_layer = layer;
          surf_templ.u.tex.last_layer = layer;
@@ -1616,7 +1628,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
          /*
           * Setup framebuffer / dest surface
           */
-         fb.cbufs[0] = surf;
+         if (is_depth) {
+            fb.nr_cbufs = 0;
+            fb.zsbuf = surf;
+         }
+         else {
+            fb.nr_cbufs = 1;
+            fb.cbufs[0] = surf;
+         }
          fb.width = u_minify(pt->width0, dstLevel);
          fb.height = u_minify(pt->height0, dstLevel);
          cso_set_framebuffer(ctx->cso, &fb);
@@ -1641,10 +1660,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
           */
          ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
          ctx->sampler.lod_bias = (float) srcLevel;
-         cso_single_sampler(ctx->cso, 0, &ctx->sampler);
-         cso_single_sampler_done(ctx->cso);
+         cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
+         cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT);
 
-         cso_set_fragment_sampler_views(ctx->cso, 1, &psv);
+         cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &psv);
 
          /* quad coords in clip coords */
          offset = set_vertex_data(ctx,
@@ -1655,6 +1674,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
          util_draw_vertex_buffer(ctx->pipe,
                                  ctx->cso,
                                  ctx->vbuf,
+                                 cso_get_aux_vertex_buffer_slot(ctx->cso),
                                  offset,
                                  PIPE_PRIM_TRIANGLE_FAN,
                                  4,  /* verts */
@@ -1669,12 +1689,16 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_restore_blend(ctx->cso);
    cso_restore_depth_stencil_alpha(ctx->cso);
    cso_restore_rasterizer(ctx->cso);
-   cso_restore_samplers(ctx->cso);
-   cso_restore_fragment_sampler_views(ctx->cso);
+   cso_restore_sample_mask(ctx->cso);
+   cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
+   cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
    cso_restore_framebuffer(ctx->cso);
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
+   cso_restore_geometry_shader(ctx->cso);
    cso_restore_viewport(ctx->cso);
-   cso_restore_clip(ctx->cso);
    cso_restore_vertex_elements(ctx->cso);
+   cso_restore_stream_outputs(ctx->cso);
+   cso_restore_aux_vertex_buffer_slot(ctx->cso);
+   cso_restore_render_condition(ctx->cso);
 }