st/xorg: fixing copies and composite shaders
authorZack Rusin <zackr@vmware.com>
Tue, 15 Sep 2009 15:01:21 +0000 (11:01 -0400)
committerZack Rusin <zackr@vmware.com>
Tue, 15 Sep 2009 23:50:36 +0000 (19:50 -0400)
copies were busted when src == dst. also the composite shaders
were incorrectly using the fragments instead of the texture coordinate.

src/gallium/state_trackers/xorg/xorg_composite.c
src/gallium/state_trackers/xorg/xorg_exa.c
src/gallium/state_trackers/xorg/xorg_exa_tgsi.c

index edb7620f1241dcc8317b93b38a72a20307125951..66ca4cb59050a1cc9545d5f1268bc8862718e402 100644 (file)
@@ -952,6 +952,61 @@ static void renderer_copy_texture(struct exa_context *exa,
    pipe_surface_reference(&dst_surf, NULL);
 }
 
+
+static struct pipe_texture *
+create_sampler_texture(struct exa_context *ctx,
+                       struct pipe_texture *src)
+{
+   enum pipe_format format;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_texture *pt;
+   struct pipe_texture templ;
+
+   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+   /* the coming in texture should already have that invariance */
+   debug_assert(screen->is_format_supported(screen, src->format,
+                                            PIPE_TEXTURE_2D,
+                                            PIPE_TEXTURE_USAGE_SAMPLER, 0));
+
+   format = src->format;
+
+   memset(&templ, 0, sizeof(templ));
+   templ.target = PIPE_TEXTURE_2D;
+   templ.format = format;
+   templ.last_level = 0;
+   templ.width[0] = src->width[0];
+   templ.height[0] = src->height[0];
+   templ.depth[0] = 1;
+   pf_get_block(format, &templ.block);
+   templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
+
+   pt = screen->texture_create(screen, &templ);
+
+   debug_assert(!pt || pipe_is_referenced(&pt->reference));
+
+   if (!pt)
+      return NULL;
+
+   {
+      /* copy source framebuffer surface into texture */
+      struct pipe_surface *ps_read = screen->get_tex_surface(
+         screen, src, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+      struct pipe_surface *ps_tex = screen->get_tex_surface(
+         screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE );
+      pipe->surface_copy(pipe,
+                        ps_tex, /* dest */
+                        0, 0, /* destx/y */
+                        ps_read,
+                        0, 0, src->width[0], src->height[0]);
+      pipe_surface_reference(&ps_read, NULL);
+      pipe_surface_reference(&ps_tex, NULL);
+   }
+
+   return pt;
+}
+
 void xorg_copy_pixmap(struct exa_context *ctx,
                       struct exa_pixmap_priv *dst_priv, int dx, int dy,
                       struct exa_pixmap_priv *src_priv, int sx, int sy,
@@ -1002,8 +1057,13 @@ void xorg_copy_pixmap(struct exa_context *ctx,
 
    if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
        dst_loc[2] >= 0 && dst_loc[3] >= 0) {
+      struct pipe_texture *temp_src = src;
+
+      if (src == dst)
+         temp_src = create_sampler_texture(ctx, src);
+
       renderer_copy_texture(ctx,
-                            src,
+                            temp_src,
                             src_loc[0],
                             src_loc[1],
                             src_loc[0] + src_loc[2],
@@ -1013,6 +1073,9 @@ void xorg_copy_pixmap(struct exa_context *ctx,
                             dst_loc[1],
                             dst_loc[0] + dst_loc[2],
                             dst_loc[1] + dst_loc[3]);
+
+      if (src == dst)
+         pipe_texture_reference(&temp_src, NULL);
    }
 }
 
index 3c2639e7d978a9d08b7d0b25d348660c45f4552f..dea9f4c2bc3fa54b902dde2fd1bf5a3bccba3e2e 100644 (file)
@@ -342,20 +342,24 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
        exa->solid_color[1] = 0.f;
        exa->solid_color[2] = 0.f;
        exa->solid_color[3] = 1.f;
-    xorg_solid(exa, priv, 0, 0, 300, 300);
-    xorg_solid(exa, priv, 300, 300, 350, 350);
-    xorg_solid(exa, priv, 350, 350, 500, 500);
-    xorg_solid(exa, priv,
+       xorg_solid(exa, priv, 0, 0, 300, 300);
+       xorg_solid(exa, priv, 300, 300, 350, 350);
+       xorg_solid(exa, priv, 350, 350, 500, 500);
+
+       xorg_solid(exa, priv,
                priv->tex->width[0] - 10,
                priv->tex->height[0] - 10,
                priv->tex->width[0],
                priv->tex->height[0]);
 
+    exa->solid_color[0] = 0.f;
+    exa->solid_color[1] = 0.f;
+    exa->solid_color[2] = 1.f;
+    exa->solid_color[3] = 1.f;
+
+    exa->has_solid_color = FALSE;
     ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff);
-    ExaCopy(pPixmap, 350, 350, 510, 350, 150, 150);
-    ExaCopy(pPixmap, 350, 350, 510, 190, 150, 150);
-    xorg_exa_finish(exa);
-    ExaCopy(pPixmap, 0, 0, 0, 0, 1024, 768);
+    ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500);
 #else
     xorg_solid(exa, priv, x0, y0, x1, y1) ;
 #endif
index d61cae53c7f0fc09949875c35632019dfe992225..2daa5b5628f48422c8d2dcde62cec2f5fd963cf6 100644 (file)
@@ -259,7 +259,7 @@ create_vs(struct pipe_context *pipe,
 
    if (is_composite) {
       src = ureg_DECL_vs_input(ureg, input_slot++);
-      dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
+      dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
       ureg_MOV(ureg, dst, src);
    }
 
@@ -310,7 +310,7 @@ create_fs(struct pipe_context *pipe,
    if (is_composite) {
       src_sampler = ureg_DECL_sampler(ureg, 0);
       src_input = ureg_DECL_fs_input(ureg,
-                                     TGSI_SEMANTIC_POSITION,
+                                     TGSI_SEMANTIC_GENERIC,
                                      0,
                                      TGSI_INTERPOLATE_PERSPECTIVE);
    } else {