i915: WIP swap rework

This commit is contained in:
Jakob Bornecrantz
2008-07-10 20:20:46 +02:00
parent 6410e94b96
commit 930a863c4f
4 changed files with 127 additions and 152 deletions
@@ -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
@@ -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;
};
+116 -147
View File
@@ -28,16 +28,13 @@
#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.
@@ -49,158 +46,130 @@
*/
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;
struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv);
struct intel_context *intel = intelScreen->dummyContext;
DBG(SWAP, "%s\n", __FUNCTION__);
DBG(SWAP, "%s\n", __FUNCTION__);
if (!intel) {
/* XXX this is where some kind of extra/meta context could be useful */
return;
}
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;
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);
/* 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);
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;
for (i = 0; i < nbox; i++, pbox++) {
drm_clip_rect_t box;
drm_clip_rect_t sbox;
ASSERT(surf->buffer);
ASSERT(surf->cpp == cpp);
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
pbox->x2 > intelScreen->front.width ||
pbox->y2 > intelScreen->front.height) {
/* invalid cliprect, skip it */
continue;
}
DBG(SWAP, "screen pitch %d src surface pitch %d\n",
pitch, surf->stride);
box = *pbox;
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);
}
if (rect) {
/* intersect cliprect with user-provided src rect */
drm_clip_rect_t rrect;
for (i = 0; i < nbox; i++, pbox++) {
drm_clip_rect_t box;
drm_clip_rect_t sbox;
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 (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
pbox->x2 > intelScreen->front.width ||
pbox->y2 > intelScreen->front.height) {
/* invalid cliprect, skip it */
continue;
}
if (box.x1 > box.x2 || box.y1 > box.y2)
continue;
}
box = *pbox;
/* 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;
if (rect) {
/* intersect cliprect with user-provided src rect */
drm_clip_rect_t rrect;
DBG(SWAP, "\tdbox x1 x2 y1 y2 %d %d %d %d\n",
box.x1, box.x2, box.y1, box.y2);
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;
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);
if (box.x1 > box.x2 || box.y1 > box.y2)
continue;
}
assert(box.x1 < box.x2);
assert(box.y1 < box.y2);
/* 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;
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);
}
DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n",
box.x1, box.x2, box.y1, box.y2);
if (intel->first_swap_fence)
driFenceUnReference(&intel->first_swap_fence);
intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch);
}
sbox.x1 = box.x1 - dPriv->x;
sbox.y1 = box.y1 - dPriv->y;
assert(box.x1 < box.x2);
assert(box.y1 < box.y2);
UNLOCK_HARDWARE(intel);
/* 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;
}
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);
}
}
@@ -29,11 +29,11 @@
#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);