mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 06:20:09 +01:00
Start re-working SwapBuffers.
intelCopyBuffer() is now intelDisplayBuffer(): it displays the given surface in the on-screen window. Added a pipe_surface parameter to winsys->flush_frontbuffer(). Front buffer rendering/flushing actually works now. But, we should only allocate the front surface on demand...
This commit is contained in:
parent
28bed6d355
commit
d8e66aca84
6 changed files with 64 additions and 52 deletions
|
|
@ -58,15 +58,33 @@ typedef struct drm_i915_flip {
|
|||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Return the pipe_surface for the given renderbuffer.
|
||||
*/
|
||||
static struct pipe_surface *
|
||||
get_color_surface(struct intel_framebuffer *intel_fb,
|
||||
GLuint bufferIndex)
|
||||
{
|
||||
struct st_renderbuffer *strb
|
||||
= st_renderbuffer(intel_fb->Base.Attachment[bufferIndex].Renderbuffer);
|
||||
if (strb)
|
||||
return strb->surface;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the back color buffer to the front color buffer.
|
||||
* Used for SwapBuffers().
|
||||
* Display a colorbuffer surface in an X window.
|
||||
* Used for SwapBuffers and flushing front buffer rendering.
|
||||
*
|
||||
* \param dPriv the window/drawable to display into
|
||||
* \param surf the surface to display
|
||||
* \param rect optional subrect of surface to display (may be NULL).
|
||||
*/
|
||||
void
|
||||
intelCopyBuffer(__DRIdrawablePrivate * dPriv,
|
||||
const drm_clip_rect_t * rect)
|
||||
intelDisplayBuffer(__DRIdrawablePrivate * dPriv,
|
||||
struct pipe_surface *surf,
|
||||
const drm_clip_rect_t * rect)
|
||||
{
|
||||
|
||||
struct intel_context *intel;
|
||||
|
|
@ -103,49 +121,24 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv,
|
|||
|
||||
if (dPriv && dPriv->numClipRects) {
|
||||
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
|
||||
#if 0
|
||||
const struct pipe_region *backRegion
|
||||
= intel_fb->Base._ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT ?
|
||||
intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT) :
|
||||
intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT);
|
||||
#endif
|
||||
const int backWidth = intel_fb->Base.Width;
|
||||
const int backHeight = intel_fb->Base.Height;
|
||||
const int nbox = dPriv->numClipRects;
|
||||
const drm_clip_rect_t *pbox = dPriv->pClipRects;
|
||||
const int pitch = intelScreen->front.pitch / intelScreen->front.cpp;
|
||||
#if 0
|
||||
const int srcpitch = backRegion->pitch;
|
||||
#endif
|
||||
const int cpp = intelScreen->front.cpp;
|
||||
int BR13, CMD;
|
||||
int i;
|
||||
|
||||
const struct pipe_surface *backSurf;
|
||||
const struct pipe_region *backRegion;
|
||||
int srcpitch;
|
||||
struct st_renderbuffer *strb;
|
||||
|
||||
/* blit from back color buffer if it exists, else front buffer */
|
||||
strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
|
||||
if (strb) {
|
||||
backSurf = strb->surface;
|
||||
}
|
||||
else {
|
||||
strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
|
||||
backSurf = strb->surface;
|
||||
}
|
||||
|
||||
backRegion = backSurf->region;
|
||||
srcpitch = backRegion->pitch;
|
||||
const struct pipe_region *srcRegion = surf->region;
|
||||
const int srcpitch= srcRegion->pitch;
|
||||
|
||||
ASSERT(intel_fb);
|
||||
ASSERT(intel_fb->Base.Name == 0); /* Not a user-created FBO */
|
||||
ASSERT(backRegion);
|
||||
ASSERT(backRegion->cpp == cpp);
|
||||
ASSERT(srcRegion);
|
||||
ASSERT(srcRegion->cpp == cpp);
|
||||
|
||||
DBG(SWAP, "front pitch %d back pitch %d\n",
|
||||
pitch, backRegion->pitch);
|
||||
pitch, srcRegion->pitch);
|
||||
|
||||
if (cpp == 2) {
|
||||
BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
|
||||
|
|
@ -164,12 +157,15 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv,
|
|||
if (pbox->x1 > pbox->x2 ||
|
||||
pbox->y1 > pbox->y2 ||
|
||||
pbox->x2 > intelScreen->front.width ||
|
||||
pbox->y2 > intelScreen->front.height)
|
||||
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;
|
||||
|
|
@ -212,7 +208,7 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv,
|
|||
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(backRegion->buffer),
|
||||
OUT_RELOC(dri_bo(srcRegion->buffer),
|
||||
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
|
||||
DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
|
||||
|
||||
|
|
@ -590,10 +586,13 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
|
|||
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
|
||||
|
||||
if (!intelScheduleSwap(dPriv, &missed_target)) {
|
||||
struct pipe_surface *back_surf
|
||||
= get_color_surface(intel_fb, BUFFER_BACK_LEFT);
|
||||
|
||||
driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags,
|
||||
&missed_target);
|
||||
|
||||
intelCopyBuffer(dPriv, NULL);
|
||||
intelDisplayBuffer(dPriv, back_surf, NULL);
|
||||
}
|
||||
|
||||
intel_fb->swap_count++;
|
||||
|
|
@ -621,6 +620,10 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
|
|||
GLcontext *ctx = intel->st->ctx;
|
||||
|
||||
if (ctx->Visual.doubleBufferMode) {
|
||||
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
|
||||
struct pipe_surface *back_surf
|
||||
= get_color_surface(intel_fb, BUFFER_BACK_LEFT);
|
||||
|
||||
drm_clip_rect_t rect;
|
||||
/* fixup cliprect (driDrawable may have changed?) later */
|
||||
rect.x1 = x;
|
||||
|
|
@ -628,7 +631,7 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
|
|||
rect.x2 = w;
|
||||
rect.y2 = h;
|
||||
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
|
||||
intelCopyBuffer(dPriv, &rect);
|
||||
intelDisplayBuffer(dPriv, back_surf, &rect);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -62,8 +62,9 @@ struct intel_framebuffer
|
|||
};
|
||||
|
||||
|
||||
void intelCopyBuffer(__DRIdrawablePrivate * dPriv,
|
||||
const drm_clip_rect_t * rect);
|
||||
extern void intelDisplayBuffer(__DRIdrawablePrivate * dPriv,
|
||||
struct pipe_surface *surf,
|
||||
const drm_clip_rect_t * rect);
|
||||
|
||||
extern void intel_wait_flips(struct intel_context *intel, GLuint batch_flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -185,12 +185,13 @@ static void intel_wait_idle( struct pipe_winsys *sws )
|
|||
* we copied its contents to the real frontbuffer. Our task is easy:
|
||||
*/
|
||||
static void
|
||||
intel_flush_frontbuffer( struct pipe_winsys *sws )
|
||||
intel_flush_frontbuffer( struct pipe_winsys *sws,
|
||||
struct pipe_surface *surf )
|
||||
{
|
||||
struct intel_context *intel = intel_pipe_winsys(sws)->intel;
|
||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||
|
||||
intelCopyBuffer(dPriv, NULL);
|
||||
|
||||
intelDisplayBuffer(dPriv, surf, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ struct pipe_buffer_handle;
|
|||
|
||||
|
||||
struct pipe_region;
|
||||
struct pipe_surface;
|
||||
|
||||
/** Opaque type */
|
||||
struct pipe_buffer_handle;
|
||||
|
|
@ -63,7 +64,8 @@ struct pipe_winsys
|
|||
* Do any special operations to ensure frontbuffer contents are
|
||||
* displayed, eg copy fake frontbuffer.
|
||||
*/
|
||||
void (*flush_frontbuffer)( struct pipe_winsys *sws );
|
||||
void (*flush_frontbuffer)( struct pipe_winsys *sws,
|
||||
struct pipe_surface *surf );
|
||||
|
||||
/** Debug output */
|
||||
void (*printf)( struct pipe_winsys *sws,
|
||||
|
|
|
|||
|
|
@ -157,14 +157,14 @@ xm_buffer_get_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
|
|||
}
|
||||
|
||||
static void
|
||||
xm_flush_frontbuffer(struct pipe_winsys *pws)
|
||||
xm_flush_frontbuffer(struct pipe_winsys *pws,
|
||||
struct pipe_surface *surf )
|
||||
{
|
||||
/*
|
||||
struct intel_context *intel = intel_pipe_winsys(sws)->intel;
|
||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||
|
||||
intelCopyBuffer(dPriv, NULL);
|
||||
*/
|
||||
/* The Xlib driver's front color surfaces are actually X Windows so
|
||||
* this flush is a no-op.
|
||||
* If we instead did front buffer rendering to a temporary XImage,
|
||||
* this would be the place to copy the Ximage to the on-screen Window.
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "main/macros.h"
|
||||
#include "st_context.h"
|
||||
#include "st_cb_flush.h"
|
||||
#include "st_cb_fbo.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
|
@ -59,9 +60,13 @@ static void st_flush(GLcontext *ctx)
|
|||
|
||||
|
||||
if (st->flags.frontbuffer_dirty) {
|
||||
struct st_renderbuffer *strb
|
||||
= st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
|
||||
struct pipe_surface *front_surf = strb->surface;
|
||||
|
||||
/* Hook for copying "fake" frontbuffer if necessary:
|
||||
*/
|
||||
st->pipe->winsys->flush_frontbuffer( st->pipe->winsys );
|
||||
st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf );
|
||||
st->flags.frontbuffer_dirty = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue