i915: WIP swap rework
authorJakob Bornecrantz <jakob@aurora.(none)>
Thu, 10 Jul 2008 18:20:46 +0000 (20:20 +0200)
committerJakob Bornecrantz <jakob@aurora.(none)>
Sun, 13 Jul 2008 14:49:00 +0000 (16:49 +0200)
src/gallium/drivers/i915simple/i915_texture.c
src/gallium/winsys/dri/intel/intel_context.h
src/gallium/winsys/dri/intel/intel_swapbuffers.c
src/gallium/winsys/dri/intel/intel_swapbuffers.h

index cf4964b26b39aa751bc5e8f81daf15bc3a71fa22..8427d8271a79295c83165ca359ed81faeff095f8 100644 (file)
@@ -79,7 +79,7 @@ static unsigned
 power_of_two(unsigned x)
 {
    unsigned value = 1;
-   while (value <= x)
+   while (value < x)
       value = value << 1;
    return value;
 }
@@ -205,8 +205,8 @@ i945_miptree_layout_2d( struct i915_texture *tex )
    unsigned nblocksx = pt->nblocksx[0];
    unsigned nblocksy = pt->nblocksy[0];
 
-#if 0 /* used for tiled display targets */
-   if (pt->last_level == 0 && pt->cpp == 4)
+#if 1 /* used for tiled display targets */
+   if (pt->last_level == 0 /*&& pt->bpp == 4*/)
       if (i915_displaytarget_layout(tex))
         return;
 #endif
index ced18da14338a9ff0fbc8619177e21ad2afd2aef..18b96217ac8b006f7d96130143ef42ec2844cb35 100644 (file)
@@ -32,6 +32,7 @@
 #include "drm.h"
 
 #include "pipe/p_debug.h"
+#include "util/u_blit.h"
 
 #include "intel_screen.h"
 #include "i915_drm.h"
@@ -82,6 +83,11 @@ struct intel_context
     * Configuration cache
     */
    driOptionCache optionCache;
+
+   /**
+    * Blit state for swapbuffers
+    */
+   struct blit_state *blit;
 };
 
 
index f751f97524591115407c784d283885c34ed191ed..6e10235e89f693f6c571995623479976970773ef 100644 (file)
 #include "intel_screen.h"
 #include "intel_context.h"
 #include "intel_swapbuffers.h"
-
+#include "intel_batchbuffer.h"
 #include "intel_reg.h"
 
-#include "pipe/p_context.h"
 #include "state_tracker/st_public.h"
 #include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-
 #include "intel_drm/ws_dri_bufmgr.h"
-#include "intel_batchbuffer.h"
+
 
 /**
  * Display a colorbuffer surface in an X window.
  */
 void
 intelDisplaySurface(__DRIdrawablePrivate *dPriv,
-                    struct pipe_surface *surf,
-                    const drm_clip_rect_t *rect)
+               struct pipe_texture *tex,
+               const drm_clip_rect_t *rect)
 {
-   struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv);
-   struct intel_context *intel = intelScreen->dummyContext;
-
-   DBG(SWAP, "%s\n", __FUNCTION__);
-
-   if (!intel) {
-      /* XXX this is where some kind of extra/meta context could be useful */
-      return;
-   }
-
-   if (intel->last_swap_fence) {
-      driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE);
-      driFenceUnReference(&intel->last_swap_fence);
-      intel->last_swap_fence = NULL;
-   }
-   intel->last_swap_fence = intel->first_swap_fence;
-   intel->first_swap_fence = NULL;
-
-   /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
-    * should work regardless.
-    */
-   LOCK_HARDWARE(intel);
-   /* if this drawable isn't currently bound the LOCK_HARDWARE done on the
-    * current context (which is what intelScreenContext should return) might
-    * not get a contended lock and thus cliprects not updated (tests/manywin)
-    */
-   if (intel_context(dPriv->driContextPriv) != intel)
-      DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv);
-
-
-   if (dPriv && dPriv->numClipRects) {
-      const int srcWidth = surf->width;
-      const int srcHeight = surf->height;
-      const int nbox = dPriv->numClipRects;
-      const drm_clip_rect_t *pbox = dPriv->pClipRects;
-      const int pitch = intelScreen->front.pitch / intelScreen->front.cpp;
-      const int cpp = intelScreen->front.cpp;
-      const int srcpitch = surf->stride / cpp;
-      int BR13, CMD;
-      int i;
-
-      ASSERT(surf->buffer);
-      ASSERT(surf->cpp == cpp);
-
-      DBG(SWAP, "screen pitch %d  src surface pitch %d\n",
-         pitch, surf->stride);
-
-      if (cpp == 2) {
-        BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
-        CMD = XY_SRC_COPY_BLT_CMD;
-      }
-      else {
-        BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
-        CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
-               XY_SRC_COPY_BLT_WRITE_RGB);
-      }
-
-      for (i = 0; i < nbox; i++, pbox++) {
-        drm_clip_rect_t box;
-        drm_clip_rect_t sbox;
-
-        if (pbox->x1 > pbox->x2 ||
-            pbox->y1 > pbox->y2 ||
-            pbox->x2 > intelScreen->front.width ||
-            pbox->y2 > intelScreen->front.height) {
-            /* invalid cliprect, skip it */
-           continue;
-         }
-
-        box = *pbox;
-
-        if (rect) {
-            /* intersect cliprect with user-provided src rect */
-           drm_clip_rect_t rrect;
-
-           rrect.x1 = dPriv->x + rect->x1;
-           rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y;
-           rrect.x2 = rect->x2 + rrect.x1;
-           rrect.y2 = rect->y2 + rrect.y1;
-           if (rrect.x1 > box.x1)
-              box.x1 = rrect.x1;
-           if (rrect.y1 > box.y1)
-              box.y1 = rrect.y1;
-           if (rrect.x2 < box.x2)
-              box.x2 = rrect.x2;
-           if (rrect.y2 < box.y2)
-              box.y2 = rrect.y2;
-
-           if (box.x1 > box.x2 || box.y1 > box.y2)
-              continue;
-        }
-
-        /* restrict blit to size of actually rendered area */
-        if (box.x2 - box.x1 > srcWidth)
-           box.x2 = srcWidth + box.x1;
-        if (box.y2 - box.y1 > srcHeight)
-           box.y2 = srcHeight + box.y1;
-
-        DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n",
-            box.x1, box.x2, box.y1, box.y2);
-
-        sbox.x1 = box.x1 - dPriv->x;
-        sbox.y1 = box.y1 - dPriv->y;
-
-         assert(box.x1 < box.x2);
-         assert(box.y1 < box.y2);
-
-         /* XXX this could be done with pipe->surface_copy() */
-        /* XXX should have its own batch buffer */
-        if (!BEGIN_BATCH(8, 2)) {
-           /*
-            * Since we share this batch buffer with a context
-            * we can't flush it since that risks a GPU lockup
-            */
-           assert(0);
-           continue;
-        }
-
-        OUT_BATCH(CMD);
-        OUT_BATCH(BR13);
-        OUT_BATCH((box.y1 << 16) | box.x1);
-        OUT_BATCH((box.y2 << 16) | box.x2);
-
-        OUT_RELOC(intelScreen->front.buffer,
-                  DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
-                  DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
-        OUT_BATCH((sbox.y1 << 16) | sbox.x1);
-        OUT_BATCH((srcpitch * cpp) & 0xffff);
-        OUT_RELOC(dri_bo(surf->buffer),
-                   DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
-                  DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
-
-      }
-
-      if (intel->first_swap_fence)
-        driFenceUnReference(&intel->first_swap_fence);
-      intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch);
-   }
-
-   UNLOCK_HARDWARE(intel);
-
-   if (intel->lastStamp != dPriv->lastStamp) {
-      intelUpdateWindowSize(dPriv);
-      intel->lastStamp = dPriv->lastStamp;
-   }
+       struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv);
+       struct intel_context *intel = intelScreen->dummyContext;
+
+       DBG(SWAP, "%s\n", __FUNCTION__);
+
+       if (!intel) {
+               /* XXX this is where some kind of extra/meta context could be useful */
+               return;
+       } else if (!intel->blit) {
+               intel->blit = util_create_blit(intel->st->pipe, intel->st->cso_context);
+       }
+
+       if (intel->last_swap_fence) {
+               driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE);
+               driFenceUnReference(&intel->last_swap_fence);
+               intel->last_swap_fence = NULL;
+       }
+       intel->last_swap_fence = intel->first_swap_fence;
+       intel->first_swap_fence = NULL;
+
+       /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
+        * should work regardless.
+        */
+       LOCK_HARDWARE(intel);
+       /* if this drawable isn't currently bound the LOCK_HARDWARE done on the
+        * current context (which is what intelScreenContext should return) might
+        * not get a contended lock and thus cliprects not updated (tests/manywin)
+        */
+       if (intel_context(dPriv->driContextPriv) != intel)
+               DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv);
+
+       if (dPriv && dPriv->numClipRects) {
+               const int srcWidth = tex->width[0];
+               const int srcHeight = tex->height[0];
+               const int nbox = dPriv->numClipRects;
+               const drm_clip_rect_t *pbox = dPriv->pClipRects;
+               int i;
+
+               assert(surf->buffer);
+               assert(surf->cpp == cpp);
+
+
+               for (i = 0; i < nbox; i++, pbox++) {
+                       drm_clip_rect_t box;
+                       drm_clip_rect_t sbox;
+
+                       if (pbox->x1 > pbox->x2 ||
+                                       pbox->y1 > pbox->y2 ||
+                                       pbox->x2 > intelScreen->front.width ||
+                                       pbox->y2 > intelScreen->front.height) {
+                               /* invalid cliprect, skip it */
+                               continue;
+                       }
+
+                       box = *pbox;
+
+                       if (rect) {
+                               /* intersect cliprect with user-provided src rect */
+                               drm_clip_rect_t rrect;
+
+                               rrect.x1 = dPriv->x + rect->x1;
+                               rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y;
+                               rrect.x2 = rect->x2 + rrect.x1;
+                               rrect.y2 = rect->y2 + rrect.y1;
+                               if (rrect.x1 > box.x1)
+                                       box.x1 = rrect.x1;
+                               if (rrect.y1 > box.y1)
+                                       box.y1 = rrect.y1;
+                               if (rrect.x2 < box.x2)
+                                       box.x2 = rrect.x2;
+                               if (rrect.y2 < box.y2)
+                                       box.y2 = rrect.y2;
+
+                               if (box.x1 > box.x2 || box.y1 > box.y2)
+                                       continue;
+                       }
+
+                       /* restrict blit to size of actually rendered area */
+                       if (box.x2 - box.x1 > srcWidth)
+                               box.x2 = srcWidth + box.x1;
+                       if (box.y2 - box.y1 > srcHeight)
+                               box.y2 = srcHeight + box.y1;
+
+                       DBG(SWAP, "\tdbox x1 x2 y1 y2 %d %d %d %d\n",
+                                       box.x1, box.x2, box.y1, box.y2);
+
+                       sbox.x1 = box.x1 - dPriv->x;
+                       sbox.y1 = box.y1 - dPriv->y;
+                       sbox.x2 = box.x2 - dPriv->x;
+                       sbox.y2 = box.y2 - dPriv->y;
+                       DBG(SWAP, "\tsbox x1 x2 y1 y2 %d %d %d %d\n",
+                                       sbox.x1, sbox.x2, sbox.y1, sbox.y2);
+
+                       assert(box.x1 < box.x2);
+                       assert(box.y1 < box.y2);
+
+                       util_blit_pixels_tex(intel->blit,
+                                       tex,
+                                       sbox.x1, sbox.y1,
+                                       sbox.x2, sbox.y2,
+                                       intelScreen->front.surface,
+                                       box.x1, box.y1,
+                                       box.x2, box.y2,
+                                       0.0,
+                                       PIPE_TEX_MIPFILTER_NEAREST);
+               }
+
+               if (intel->first_swap_fence)
+                       driFenceUnReference(&intel->first_swap_fence);
+               intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch);
+       }
+
+
+       UNLOCK_HARDWARE(intel);
+
+       if (intel->lastStamp != dPriv->lastStamp) {
+               intelUpdateWindowSize(dPriv);
+               intel->lastStamp = dPriv->lastStamp;
+       }
 }
 
-
-
 /**
  * This will be called whenever the currently bound window is moved/resized.
  */
@@ -212,27 +181,27 @@ intelUpdateWindowSize(__DRIdrawablePrivate *dPriv)
    st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h);
 }
 
-
-
+/**
+ * Called from glx code
+ */
 void
 intelSwapBuffers(__DRIdrawablePrivate * dPriv)
 {
    struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv);
-   struct pipe_surface *back_surf;
+   struct pipe_texture *back_tex;
 
    assert(intel_fb);
    assert(intel_fb->stfb);
 
-   back_surf = st_get_framebuffer_surface(intel_fb->stfb,
-                                          ST_SURFACE_BACK_LEFT);
-   if (back_surf) {
+   back_tex = st_get_framebuffer_texture(intel_fb->stfb,
+                                         ST_SURFACE_BACK_LEFT);
+   if (back_tex) {
       st_notify_swapbuffers(intel_fb->stfb);
-      intelDisplaySurface(dPriv, back_surf, NULL);
+      intelDisplaySurface(dPriv, back_tex, NULL);
       st_notify_swapbuffers_complete(intel_fb->stfb);
    }
 }
 
-
 /**
  * Called via glXCopySubBufferMESA() to copy a subrect of the back
  * buffer to the front buffer/screen.
@@ -241,14 +210,14 @@ void
 intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
 {
    struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv);
-   struct pipe_surface *back_surf;
+   struct pipe_texture *back_tex;
 
    assert(intel_fb);
    assert(intel_fb->stfb);
 
-   back_surf = st_get_framebuffer_surface(intel_fb->stfb,
-                                          ST_SURFACE_BACK_LEFT);
-   if (back_surf) {
+   back_tex = st_get_framebuffer_texture(intel_fb->stfb,
+                                         ST_SURFACE_BACK_LEFT);
+   if (back_tex) {
       drm_clip_rect_t rect;
       rect.x1 = x;
       rect.y1 = y;
@@ -256,6 +225,6 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
       rect.y2 = h;
 
       st_notify_swapbuffers(intel_fb->stfb);
-      intelDisplaySurface(dPriv, back_surf, &rect);
+      intelDisplaySurface(dPriv, back_tex, &rect);
    }
 }
index 46c9bab3af2a74750de0833781c57c872423fb2c..88c479f81d223da66e2a73933539e3eb939361f4 100644 (file)
 #define INTEL_SWAPBUFFERS_H
 
 
-struct pipe_surface;
+struct pipe_texture;
 
 
 extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv,
-                                struct pipe_surface *surf,
+                                struct pipe_texture *surf,
                                 const drm_clip_rect_t * rect);
 
 extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv);