Merge branch 'mesa_7_5_branch'
Conflicts: src/mesa/main/state.c
This commit is contained in:
@@ -43,6 +43,11 @@ tbd
|
||||
<h2>Bug fixes</h2>
|
||||
<ul>
|
||||
<li>Added missing GLEW library to MesaDemos tarballs.
|
||||
<li>Fixed swapbuffers jerkiness in Doom3/etc in Intel drivers.
|
||||
<li>Fixed front buffer rendering bug in Intel drivers.
|
||||
<li>Fixed minor GLX memory leaks.
|
||||
<li>Fixed some texture env / fragment program state bugs.
|
||||
<li>Fixed some Gallium glBlitFramebuffer() bugs
|
||||
</ul>
|
||||
|
||||
|
||||
|
@@ -378,6 +378,9 @@ make_window( Display *dpy, const char *name,
|
||||
scrnum = DefaultScreen( dpy );
|
||||
root = RootWindow( dpy, scrnum );
|
||||
|
||||
if (visinfo)
|
||||
XFree(visinfo);
|
||||
|
||||
visinfo = glXChooseVisual( dpy, scrnum, attribs );
|
||||
if (!visinfo) {
|
||||
printf("Error: couldn't get an RGB, Double-buffered visual\n");
|
||||
|
@@ -587,6 +587,9 @@ event_loop(Display *dpy, Window win)
|
||||
angle += 2.0;
|
||||
|
||||
draw();
|
||||
|
||||
glXSwapBuffers(dpy, win);
|
||||
|
||||
if ( get_frame_usage != NULL ) {
|
||||
GLfloat temp;
|
||||
|
||||
@@ -594,8 +597,6 @@ event_loop(Display *dpy, Window win)
|
||||
frame_usage += temp;
|
||||
}
|
||||
|
||||
glXSwapBuffers(dpy, win);
|
||||
|
||||
/* calc framerate */
|
||||
{
|
||||
static int t0 = -1;
|
||||
|
@@ -155,7 +155,11 @@ util_destroy_blit(struct blit_state *ctx)
|
||||
}
|
||||
|
||||
|
||||
static unsigned get_next_slot( struct blit_state *ctx )
|
||||
/**
|
||||
* Get offset of next free slot in vertex buffer for quad vertices.
|
||||
*/
|
||||
static unsigned
|
||||
get_next_slot( struct blit_state *ctx )
|
||||
{
|
||||
const unsigned max_slots = 4096 / sizeof ctx->vertices;
|
||||
|
||||
@@ -173,7 +177,6 @@ static unsigned get_next_slot( struct blit_state *ctx )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Setup vertex data for the textured quad we'll draw.
|
||||
* Note: y=0=top
|
||||
@@ -260,9 +263,38 @@ setup_vertex_data_tex(struct blit_state *ctx,
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \return TRUE if two regions overlap, FALSE otherwise
|
||||
*/
|
||||
static boolean
|
||||
regions_overlap(int srcX0, int srcY0,
|
||||
int srcX1, int srcY1,
|
||||
int dstX0, int dstY0,
|
||||
int dstX1, int dstY1)
|
||||
{
|
||||
if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1))
|
||||
return FALSE; /* src completely left of dst */
|
||||
|
||||
if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1))
|
||||
return FALSE; /* dst completely left of src */
|
||||
|
||||
if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1))
|
||||
return FALSE; /* src completely above dst */
|
||||
|
||||
if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1))
|
||||
return FALSE; /* dst completely above src */
|
||||
|
||||
return TRUE; /* some overlap */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy pixel block from src surface to dst surface.
|
||||
* Overlapping regions are acceptable.
|
||||
* Flipping and stretching are supported.
|
||||
* XXX what about clipping???
|
||||
* XXX need some control over blitting Z and/or stencil.
|
||||
*/
|
||||
void
|
||||
@@ -285,10 +317,40 @@ util_blit_pixels(struct blit_state *ctx,
|
||||
const int srcLeft = MIN2(srcX0, srcX1);
|
||||
const int srcTop = MIN2(srcY0, srcY1);
|
||||
unsigned offset;
|
||||
boolean overlap;
|
||||
|
||||
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
|
||||
filter == PIPE_TEX_MIPFILTER_LINEAR);
|
||||
|
||||
assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_SAMPLER, 0));
|
||||
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_SAMPLER, 0));
|
||||
|
||||
/* do the regions overlap? */
|
||||
overlap = (src == dst) && regions_overlap(srcX0, srcY0, srcX1, srcY1,
|
||||
dstX0, dstY0, dstX1, dstY1);
|
||||
|
||||
/*
|
||||
* Check for simple case: no format conversion, no flipping, no stretching,
|
||||
* no overlapping.
|
||||
*/
|
||||
if (dst->format == src->format &&
|
||||
srcX0 < srcX1 &&
|
||||
dstX0 < dstX1 &&
|
||||
srcY0 < srcY1 &&
|
||||
dstY0 < dstY1 &&
|
||||
(dstX1 - dstX0) == (srcX1 - srcX0) &&
|
||||
(dstY1 - dstY0) == (srcY1 - srcY0) &&
|
||||
!overlap) {
|
||||
/* FIXME: this will most surely fail for overlapping rectangles */
|
||||
pipe->surface_copy(pipe,
|
||||
dst, dstX0, dstY0, /* dest */
|
||||
src, srcX0, srcY0, /* src */
|
||||
srcW, srcH); /* size */
|
||||
return;
|
||||
}
|
||||
|
||||
if (srcLeft != srcX0) {
|
||||
/* left-right flip */
|
||||
int tmp = dstX0;
|
||||
@@ -303,20 +365,6 @@ util_blit_pixels(struct blit_state *ctx,
|
||||
dstY1 = tmp;
|
||||
}
|
||||
|
||||
assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_SAMPLER, 0));
|
||||
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_SAMPLER, 0));
|
||||
|
||||
if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) {
|
||||
/* FIXME: this will most surely fail for overlapping rectangles */
|
||||
pipe->surface_copy(pipe,
|
||||
dst, dstX0, dstY0, /* dest */
|
||||
src, srcX0, srcY0, /* src */
|
||||
srcW, srcH); /* size */
|
||||
return;
|
||||
}
|
||||
|
||||
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
|
||||
|
||||
|
@@ -201,6 +201,11 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
|
||||
drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
|
||||
}
|
||||
|
||||
if (intel->first_post_swapbuffers_batch == NULL) {
|
||||
intel->first_post_swapbuffers_batch = intel->batch->buf;
|
||||
drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
|
||||
}
|
||||
|
||||
if (used == 0) {
|
||||
batch->cliprect_mode = IGNORE_CLIPRECTS;
|
||||
return;
|
||||
|
@@ -2038,7 +2038,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
if (mask & GL_STENCIL_BUFFER_BIT) {
|
||||
struct gl_renderbuffer *readRb = readFb->_StencilBuffer;
|
||||
struct gl_renderbuffer *drawRb = drawFb->_StencilBuffer;
|
||||
if (readRb->StencilBits != drawRb->StencilBits) {
|
||||
if (!readRb ||
|
||||
!drawRb ||
|
||||
readRb->StencilBits != drawRb->StencilBits) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBlitFramebufferEXT(stencil buffer size mismatch");
|
||||
return;
|
||||
@@ -2048,7 +2050,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
if (mask & GL_DEPTH_BUFFER_BIT) {
|
||||
struct gl_renderbuffer *readRb = readFb->_DepthBuffer;
|
||||
struct gl_renderbuffer *drawRb = drawFb->_DepthBuffer;
|
||||
if (readRb->DepthBits != drawRb->DepthBits) {
|
||||
if (!readRb ||
|
||||
!drawRb ||
|
||||
readRb->DepthBits != drawRb->DepthBits) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glBlitFramebufferEXT(depth buffer size mismatch");
|
||||
return;
|
||||
|
@@ -5335,3 +5335,181 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clip dst coords against Xmax (or Ymax).
|
||||
*/
|
||||
static INLINE void
|
||||
clip_right_or_top(GLint *srcX0, GLint *srcX1,
|
||||
GLint *dstX0, GLint *dstX1,
|
||||
GLint maxValue)
|
||||
{
|
||||
GLfloat t, bias;
|
||||
|
||||
if (*dstX1 > maxValue) {
|
||||
/* X1 outside right edge */
|
||||
ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
|
||||
t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
|
||||
/* chop off [t, 1] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX1 = maxValue;
|
||||
bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
|
||||
*srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
|
||||
}
|
||||
else if (*dstX0 > maxValue) {
|
||||
/* X0 outside right edge */
|
||||
ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
|
||||
t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
|
||||
/* chop off [t, 1] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX0 = maxValue;
|
||||
bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
|
||||
*srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clip dst coords against Xmin (or Ymin).
|
||||
*/
|
||||
static INLINE void
|
||||
clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
|
||||
GLint *dstX0, GLint *dstX1,
|
||||
GLint minValue)
|
||||
{
|
||||
GLfloat t, bias;
|
||||
|
||||
if (*dstX0 < minValue) {
|
||||
/* X0 outside left edge */
|
||||
ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
|
||||
t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
|
||||
/* chop off [0, t] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX0 = minValue;
|
||||
bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
|
||||
*srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
|
||||
}
|
||||
else if (*dstX1 < minValue) {
|
||||
/* X1 outside left edge */
|
||||
ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
|
||||
t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
|
||||
/* chop off [0, t] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX1 = minValue;
|
||||
bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
|
||||
*srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do clipping of blit src/dest rectangles.
|
||||
* The dest rect is clipped against both the buffer bounds and scissor bounds.
|
||||
* The src rect is just clipped against the buffer bounds.
|
||||
*
|
||||
* When either the src or dest rect is clipped, the other is also clipped
|
||||
* proportionately!
|
||||
*
|
||||
* Note that X0 need not be less than X1 (same for Y) for either the source
|
||||
* and dest rects. That makes the clipping a little trickier.
|
||||
*
|
||||
* \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
|
||||
*/
|
||||
GLboolean
|
||||
_mesa_clip_blit(GLcontext *ctx,
|
||||
GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
|
||||
GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
|
||||
{
|
||||
const GLint srcXmin = 0;
|
||||
const GLint srcXmax = ctx->ReadBuffer->Width;
|
||||
const GLint srcYmin = 0;
|
||||
const GLint srcYmax = ctx->ReadBuffer->Height;
|
||||
|
||||
/* these include scissor bounds */
|
||||
const GLint dstXmin = ctx->DrawBuffer->_Xmin;
|
||||
const GLint dstXmax = ctx->DrawBuffer->_Xmax;
|
||||
const GLint dstYmin = ctx->DrawBuffer->_Ymin;
|
||||
const GLint dstYmax = ctx->DrawBuffer->_Ymax;
|
||||
|
||||
/*
|
||||
printf("PreClipX: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcX0, *srcX1, *dstX0, *dstX1);
|
||||
printf("PreClipY: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcY0, *srcY1, *dstY0, *dstY1);
|
||||
*/
|
||||
|
||||
/* trivial rejection tests */
|
||||
if (*dstX0 == *dstX1)
|
||||
return GL_FALSE; /* no width */
|
||||
if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
|
||||
return GL_FALSE; /* totally out (left) of bounds */
|
||||
if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
|
||||
return GL_FALSE; /* totally out (right) of bounds */
|
||||
|
||||
if (*dstY0 == *dstY1)
|
||||
return GL_FALSE;
|
||||
if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
|
||||
return GL_FALSE;
|
||||
if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
|
||||
return GL_FALSE;
|
||||
|
||||
if (*srcX0 == *srcX1)
|
||||
return GL_FALSE;
|
||||
if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
|
||||
return GL_FALSE;
|
||||
if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
|
||||
return GL_FALSE;
|
||||
|
||||
if (*srcY0 == *srcY1)
|
||||
return GL_FALSE;
|
||||
if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
|
||||
return GL_FALSE;
|
||||
if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
|
||||
return GL_FALSE;
|
||||
|
||||
/*
|
||||
* dest clip
|
||||
*/
|
||||
clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
|
||||
clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
|
||||
clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
|
||||
clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
|
||||
|
||||
/*
|
||||
* src clip (just swap src/dst values from above)
|
||||
*/
|
||||
clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
|
||||
clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
|
||||
clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
|
||||
clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
|
||||
|
||||
/*
|
||||
printf("PostClipX: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcX0, *srcX1, *dstX0, *dstX1);
|
||||
printf("PostClipY: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcY0, *srcY1, *dstY0, *dstY1);
|
||||
*/
|
||||
|
||||
ASSERT(*dstX0 >= dstXmin);
|
||||
ASSERT(*dstX0 <= dstXmax);
|
||||
ASSERT(*dstX1 >= dstXmin);
|
||||
ASSERT(*dstX1 <= dstXmax);
|
||||
|
||||
ASSERT(*dstY0 >= dstYmin);
|
||||
ASSERT(*dstY0 <= dstYmax);
|
||||
ASSERT(*dstY1 >= dstYmin);
|
||||
ASSERT(*dstY1 <= dstYmax);
|
||||
|
||||
ASSERT(*srcX0 >= srcXmin);
|
||||
ASSERT(*srcX0 <= srcXmax);
|
||||
ASSERT(*srcX1 >= srcXmin);
|
||||
ASSERT(*srcX1 <= srcXmax);
|
||||
|
||||
ASSERT(*srcY0 >= srcYmin);
|
||||
ASSERT(*srcY0 <= srcYmax);
|
||||
ASSERT(*srcY1 >= srcYmin);
|
||||
ASSERT(*srcY1 <= srcYmax);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
@@ -291,4 +291,10 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height );
|
||||
|
||||
extern GLboolean
|
||||
_mesa_clip_blit(GLcontext *ctx,
|
||||
GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
|
||||
GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -69,34 +69,107 @@ st_BlitFramebuffer(GLcontext *ctx,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter)
|
||||
{
|
||||
const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
|
||||
GL_STENCIL_BUFFER_BIT);
|
||||
struct st_context *st = ctx->st;
|
||||
|
||||
const uint pFilter = ((filter == GL_NEAREST)
|
||||
? PIPE_TEX_MIPFILTER_NEAREST
|
||||
: PIPE_TEX_MIPFILTER_LINEAR);
|
||||
struct gl_framebuffer *readFB = ctx->ReadBuffer;
|
||||
struct gl_framebuffer *drawFB = ctx->DrawBuffer;
|
||||
|
||||
if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
|
||||
&dstX0, &dstY0, &dstX1, &dstY1)) {
|
||||
return; /* nothing to draw/blit */
|
||||
}
|
||||
|
||||
if (st_fb_orientation(drawFB) == Y_0_TOP) {
|
||||
/* invert Y for dest */
|
||||
dstY0 = drawFB->Height - dstY0;
|
||||
dstY1 = drawFB->Height - dstY1;
|
||||
}
|
||||
|
||||
if (st_fb_orientation(readFB) == Y_0_TOP) {
|
||||
/* invert Y for src */
|
||||
srcY0 = readFB->Height - srcY0;
|
||||
srcY1 = readFB->Height - srcY1;
|
||||
}
|
||||
|
||||
if (srcY0 > srcY1 && dstY0 > dstY1) {
|
||||
/* Both src and dst are upside down. Swap Y to make it
|
||||
* right-side up to increase odds of using a fast path.
|
||||
* Recall that all Gallium raster coords have Y=0=top.
|
||||
*/
|
||||
GLint tmp;
|
||||
tmp = srcY0;
|
||||
srcY0 = srcY1;
|
||||
srcY1 = tmp;
|
||||
tmp = dstY0;
|
||||
dstY0 = dstY1;
|
||||
dstY1 = tmp;
|
||||
}
|
||||
|
||||
if (mask & GL_COLOR_BUFFER_BIT) {
|
||||
struct st_renderbuffer *srcRb =
|
||||
st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
|
||||
st_renderbuffer(readFB->_ColorReadBuffer);
|
||||
struct st_renderbuffer *dstRb =
|
||||
st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
|
||||
st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
|
||||
struct pipe_surface *srcSurf = srcRb->surface;
|
||||
struct pipe_surface *dstSurf = dstRb->surface;
|
||||
|
||||
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
|
||||
/* invert Y */
|
||||
srcY0 = srcRb->Base.Height - srcY0;
|
||||
srcY1 = srcRb->Base.Height - srcY1;
|
||||
|
||||
dstY0 = dstRb->Base.Height - dstY0;
|
||||
dstY1 = dstRb->Base.Height - dstY1;
|
||||
}
|
||||
|
||||
util_blit_pixels(st->blit,
|
||||
srcSurf, srcX0, srcY0, srcX1, srcY1,
|
||||
dstSurf, dstX0, dstY0, dstX1, dstY1,
|
||||
0.0, pFilter);
|
||||
}
|
||||
|
||||
if (mask & depthStencil) {
|
||||
/* depth and/or stencil blit */
|
||||
|
||||
/* get src/dst depth surfaces */
|
||||
struct st_renderbuffer *srcDepthRb =
|
||||
st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
|
||||
struct st_renderbuffer *dstDepthRb =
|
||||
st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
|
||||
struct pipe_surface *srcDepthSurf =
|
||||
srcDepthRb ? srcDepthRb->surface : NULL;
|
||||
struct pipe_surface *dstDepthSurf =
|
||||
dstDepthRb ? dstDepthRb->surface : NULL;
|
||||
|
||||
/* get src/dst stencil surfaces */
|
||||
struct st_renderbuffer *srcStencilRb =
|
||||
st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer);
|
||||
struct st_renderbuffer *dstStencilRb =
|
||||
st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer);
|
||||
struct pipe_surface *srcStencilSurf =
|
||||
srcStencilRb ? srcStencilRb->surface : NULL;
|
||||
struct pipe_surface *dstStencilSurf =
|
||||
dstStencilRb ? dstStencilRb->surface : NULL;
|
||||
|
||||
if ((mask & depthStencil) == depthStencil &&
|
||||
srcDepthSurf == srcStencilSurf &&
|
||||
dstDepthSurf == dstStencilSurf) {
|
||||
/* Blitting depth and stencil values between combined
|
||||
* depth/stencil buffers. This is the ideal case for such buffers.
|
||||
*/
|
||||
util_blit_pixels(st->blit,
|
||||
srcDepthSurf, srcX0, srcY0, srcX1, srcY1,
|
||||
dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
|
||||
0.0, pFilter);
|
||||
}
|
||||
else {
|
||||
/* blitting depth and stencil separately */
|
||||
|
||||
if (mask & GL_DEPTH_BUFFER_BIT) {
|
||||
/* blit Z only */
|
||||
_mesa_problem(ctx, "st_BlitFramebuffer(DEPTH) not completed");
|
||||
}
|
||||
|
||||
if (mask & GL_STENCIL_BUFFER_BIT) {
|
||||
/* blit stencil only */
|
||||
_mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) not completed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -233,7 +233,9 @@ void st_init_extensions(struct st_context *st)
|
||||
|
||||
if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) {
|
||||
ctx->Extensions.ARB_point_sprite = GL_TRUE;
|
||||
ctx->Extensions.NV_point_sprite = GL_TRUE;
|
||||
/* GL_NV_point_sprite is not supported by gallium because we don't
|
||||
* support the GL_POINT_SPRITE_R_MODE_NV option.
|
||||
*/
|
||||
}
|
||||
|
||||
if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
|
||||
|
@@ -24,6 +24,7 @@
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/image.h"
|
||||
#include "main/macros.h"
|
||||
#include "s_context.h"
|
||||
|
||||
@@ -550,184 +551,6 @@ simple_blit(GLcontext *ctx,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clip dst coords against Xmax (or Ymax).
|
||||
*/
|
||||
static INLINE void
|
||||
clip_right_or_top(GLint *srcX0, GLint *srcX1,
|
||||
GLint *dstX0, GLint *dstX1,
|
||||
GLint maxValue)
|
||||
{
|
||||
GLfloat t, bias;
|
||||
|
||||
if (*dstX1 > maxValue) {
|
||||
/* X1 outside right edge */
|
||||
ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
|
||||
t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
|
||||
/* chop off [t, 1] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX1 = maxValue;
|
||||
bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
|
||||
*srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
|
||||
}
|
||||
else if (*dstX0 > maxValue) {
|
||||
/* X0 outside right edge */
|
||||
ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
|
||||
t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
|
||||
/* chop off [t, 1] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX0 = maxValue;
|
||||
bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
|
||||
*srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clip dst coords against Xmin (or Ymin).
|
||||
*/
|
||||
static INLINE void
|
||||
clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
|
||||
GLint *dstX0, GLint *dstX1,
|
||||
GLint minValue)
|
||||
{
|
||||
GLfloat t, bias;
|
||||
|
||||
if (*dstX0 < minValue) {
|
||||
/* X0 outside left edge */
|
||||
ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
|
||||
t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
|
||||
/* chop off [0, t] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX0 = minValue;
|
||||
bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
|
||||
*srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
|
||||
}
|
||||
else if (*dstX1 < minValue) {
|
||||
/* X1 outside left edge */
|
||||
ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
|
||||
t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
|
||||
/* chop off [0, t] part */
|
||||
ASSERT(t >= 0.0 && t <= 1.0);
|
||||
*dstX1 = minValue;
|
||||
bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
|
||||
*srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do clipping of blit src/dest rectangles.
|
||||
* The dest rect is clipped against both the buffer bounds and scissor bounds.
|
||||
* The src rect is just clipped against the buffer bounds.
|
||||
*
|
||||
* When either the src or dest rect is clipped, the other is also clipped
|
||||
* proportionately!
|
||||
*
|
||||
* Note that X0 need not be less than X1 (same for Y) for either the source
|
||||
* and dest rects. That makes the clipping a little trickier.
|
||||
*
|
||||
* \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
|
||||
*/
|
||||
static GLboolean
|
||||
clip_blit(GLcontext *ctx,
|
||||
GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
|
||||
GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
|
||||
{
|
||||
const GLint srcXmin = 0;
|
||||
const GLint srcXmax = ctx->ReadBuffer->Width;
|
||||
const GLint srcYmin = 0;
|
||||
const GLint srcYmax = ctx->ReadBuffer->Height;
|
||||
|
||||
/* these include scissor bounds */
|
||||
const GLint dstXmin = ctx->DrawBuffer->_Xmin;
|
||||
const GLint dstXmax = ctx->DrawBuffer->_Xmax;
|
||||
const GLint dstYmin = ctx->DrawBuffer->_Ymin;
|
||||
const GLint dstYmax = ctx->DrawBuffer->_Ymax;
|
||||
|
||||
/*
|
||||
printf("PreClipX: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcX0, *srcX1, *dstX0, *dstX1);
|
||||
printf("PreClipY: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcY0, *srcY1, *dstY0, *dstY1);
|
||||
*/
|
||||
|
||||
/* trivial rejection tests */
|
||||
if (*dstX0 == *dstX1)
|
||||
return GL_FALSE; /* no width */
|
||||
if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
|
||||
return GL_FALSE; /* totally out (left) of bounds */
|
||||
if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
|
||||
return GL_FALSE; /* totally out (right) of bounds */
|
||||
|
||||
if (*dstY0 == *dstY1)
|
||||
return GL_FALSE;
|
||||
if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
|
||||
return GL_FALSE;
|
||||
if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
|
||||
return GL_FALSE;
|
||||
|
||||
if (*srcX0 == *srcX1)
|
||||
return GL_FALSE;
|
||||
if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
|
||||
return GL_FALSE;
|
||||
if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
|
||||
return GL_FALSE;
|
||||
|
||||
if (*srcY0 == *srcY1)
|
||||
return GL_FALSE;
|
||||
if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
|
||||
return GL_FALSE;
|
||||
if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
|
||||
return GL_FALSE;
|
||||
|
||||
/*
|
||||
* dest clip
|
||||
*/
|
||||
clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
|
||||
clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
|
||||
clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
|
||||
clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
|
||||
|
||||
/*
|
||||
* src clip (just swap src/dst values from above)
|
||||
*/
|
||||
clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
|
||||
clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
|
||||
clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
|
||||
clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
|
||||
|
||||
/*
|
||||
printf("PostClipX: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcX0, *srcX1, *dstX0, *dstX1);
|
||||
printf("PostClipY: src: %d .. %d dst: %d .. %d\n",
|
||||
*srcY0, *srcY1, *dstY0, *dstY1);
|
||||
*/
|
||||
|
||||
ASSERT(*dstX0 >= dstXmin);
|
||||
ASSERT(*dstX0 <= dstXmax);
|
||||
ASSERT(*dstX1 >= dstXmin);
|
||||
ASSERT(*dstX1 <= dstXmax);
|
||||
|
||||
ASSERT(*dstY0 >= dstYmin);
|
||||
ASSERT(*dstY0 <= dstYmax);
|
||||
ASSERT(*dstY1 >= dstYmin);
|
||||
ASSERT(*dstY1 <= dstYmax);
|
||||
|
||||
ASSERT(*srcX0 >= srcXmin);
|
||||
ASSERT(*srcX0 <= srcXmax);
|
||||
ASSERT(*srcX1 >= srcXmin);
|
||||
ASSERT(*srcX1 <= srcXmax);
|
||||
|
||||
ASSERT(*srcY0 >= srcYmin);
|
||||
ASSERT(*srcY0 <= srcYmax);
|
||||
ASSERT(*srcY1 >= srcYmin);
|
||||
ASSERT(*srcY1 <= srcYmax);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Software fallback for glBlitFramebufferEXT().
|
||||
*/
|
||||
@@ -747,7 +570,7 @@ _swrast_BlitFramebuffer(GLcontext *ctx,
|
||||
if (!ctx->DrawBuffer->_NumColorDrawBuffers)
|
||||
return;
|
||||
|
||||
if (!clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
|
||||
if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
|
||||
&dstX0, &dstY0, &dstX1, &dstY1)) {
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user