From ed6125fe9b2a806103cc58a60027aa2aba64dd2f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 3 Aug 2009 11:16:23 -0600 Subject: st/mesa: we don't support GL_NV_point_sprite (see comment) --- src/mesa/state_tracker/st_extensions.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index e6728ae8955..9f6564dbc5d 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -222,7 +222,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)) { -- cgit v1.2.3 From 0ce73f84e9f4d992c1108ce2c84718bc0fcada96 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 20 Jul 2009 16:11:26 +1000 Subject: Add missing X11_INCLUDES to egl/drivers/demo and egl/main. Compiling mesa on a system with no X headers installed in the default include paths fails due to missing X11 includes. The header includes are picked up by configure but not applied. Signed-off-by: Peter Hutterer Signed-off-by: Dave Airlie (cherry picked from commit 5358e54d1ae64ccfa81199b343a2931b415fcc0a) --- src/egl/drivers/demo/Makefile | 2 +- src/egl/main/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/egl/drivers/demo/Makefile b/src/egl/drivers/demo/Makefile index 26694c92fa6..444dfb35bde 100644 --- a/src/egl/drivers/demo/Makefile +++ b/src/egl/drivers/demo/Makefile @@ -4,7 +4,7 @@ TOP = ../../../.. include $(TOP)/configs/current -INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main +INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main $(X11_INCLUDES) SOURCES = demo.c diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index 8cfa25ca163..fab8f160891 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -4,7 +4,7 @@ TOP = ../../.. include $(TOP)/configs/current -INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi +INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES) HEADERS = \ eglconfig.h \ -- cgit v1.2.3 From 9d3929b60c9d4dd4403bcc63cb65d2673cf98b0e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Aug 2009 09:14:33 -0600 Subject: texenv: Add missing dependency on VP changes. Funny thing is I annotated this dependency in e5f63c403b767f9974e8eb5d412c012b8a69287f, but didn't actually use it. (cherry picked from master, commit 03187571b63d97e3d1406d329c5e760e16ef3181) Conflicts: src/mesa/main/state.c --- src/mesa/main/state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 1d3758a302b..51726461b6c 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -502,7 +502,8 @@ _mesa_update_state_locked( GLcontext *ctx ) /* Determine which state flags effect vertex/fragment program state */ if (ctx->FragmentProgram._MaintainTexEnvProgram) { prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR | - _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE); + _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE | + _NEW_PROGRAM); } if (ctx->VertexProgram._MaintainTnlProgram) { prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | -- cgit v1.2.3 From f0df08abbec173be183d3d6ecf3d4ba5206df179 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Aug 2009 09:15:09 -0600 Subject: texenv: Match state.c in deciding whether we'll be using a vertex shader. (cherry picked from master, commit 40990d9dfb20b69585859b2a45596aa46c20140a) --- src/mesa/main/texenvprogram.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index a3f1246c985..8229de4c475 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -263,6 +263,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx ) { /* _NEW_PROGRAM */ const GLboolean vertexShader = (ctx->Shader.CurrentProgram && + ctx->Shader.CurrentProgram->LinkStatus && ctx->Shader.CurrentProgram->VertexProgram); const GLboolean vertexProgram = ctx->VertexProgram._Enabled; GLbitfield fp_inputs = 0x0; -- cgit v1.2.3 From 2bec909c69c127b4a29eedfcafed9f5f2e23c51e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Aug 2009 09:15:33 -0600 Subject: texenv: Use VP->Current, since _Current isn't updated at this point. (cherry picked from master, commit a9ba1bfeb3a2852c6eda718e73c46c972a286648) --- src/mesa/main/texenvprogram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 8229de4c475..3ff30058ecf 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -329,7 +329,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx ) if (vertexShader) vprog = ctx->Shader.CurrentProgram->VertexProgram; else - vprog = ctx->VertexProgram._Current; + vprog = ctx->VertexProgram.Current; vp_outputs = vprog->Base.OutputsWritten; -- cgit v1.2.3 From f5f8be8bb2dae91e0eb748b6f062eeb345605063 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Aug 2009 09:22:15 -0600 Subject: intel: Wait on the last swapbuffers to complete before queuing a new one. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes jerkiness in doom3 and other apps since the kernel change to throttle less absurdly, which led to a thundering herd of frames. Because this is a rather minimal fix, there is at least one downside: If the whole scene completes in one batchbuffer, we'll end up stalling the GPU. Thanks to Michel Dänzer for suggesting using glFlush to signal frame end instead of going to all the effort of adding a new DRI2 extension. (cherry picked from master, commit 0828579a658af01a64b5e699175dc9bbbedcd685) --- src/mesa/drivers/dri/intel/intel_batchbuffer.c | 5 +++++ src/mesa/drivers/dri/intel/intel_context.c | 22 ++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_context.h | 1 + 3 files changed, 28 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 29dc05c518e..82a92a9f454 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -197,6 +197,11 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, GLuint used = batch->ptr - batch->map; GLboolean was_locked = intel->locked; + 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; diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 9db5b546433..a40951abe39 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -521,7 +521,27 @@ intelFlush(GLcontext * ctx) static void intel_glFlush(GLcontext *ctx) { + struct intel_context *intel = intel_context(ctx); + intel_flush(ctx, GL_TRUE); + + /* We're using glFlush as an indicator that a frame is done, which is + * what DRI2 does before calling SwapBuffers (and means we should catch + * people doing front-buffer rendering, as well).. + * + * Wait for the swapbuffers before the one we just emitted, so we don't + * get too many swaps outstanding for apps that are GPU-heavy but not + * CPU-heavy. + * + * Unfortunately, we don't have a handle to the batch containing the swap, + * and getting our hands on that doesn't seem worth it, so we just us the + * first batch we emitted after the last swap. + */ + if (intel->first_post_swapbuffers_batch != NULL) { + drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch); + drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); + intel->first_post_swapbuffers_batch = NULL; + } } void @@ -787,6 +807,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->prim.vb = NULL; dri_bo_unreference(intel->prim.vb_bo); intel->prim.vb_bo = NULL; + dri_bo_unreference(intel->first_post_swapbuffers_batch); + intel->first_post_swapbuffers_batch = NULL; if (release_texture_heaps) { /* This share group is about to go away, free our private diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index b5cf7e6648e..b3db561fd5b 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -191,6 +191,7 @@ struct intel_context GLboolean ttm; struct intel_batchbuffer *batch; + drm_intel_bo *first_post_swapbuffers_batch; GLboolean no_batch_wrap; unsigned batch_id; -- cgit v1.2.3 From 61673aebb0c92bf187189c496e6c3a856825eceb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Aug 2009 09:23:17 -0600 Subject: intel: Fix inverted test for disabling flushing of front buffer output. The comment disagreed with the code, and nicely drew my eyes to what was going wrong. Bug #21774 (blender) Bug #21788 (readpix) (cherry picked from master, commit fd65418f600874b05f902b622078b40bc1abb24a) --- src/mesa/drivers/dri/intel/intel_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index a40951abe39..50ae677d203 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -505,7 +505,7 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) * each of N places that do rendering. This has worse performances, * but it is much easier to get correct. */ - if (intel->is_front_buffer_rendering) { + if (!intel->is_front_buffer_rendering) { intel->front_buffer_dirty = GL_FALSE; } } -- cgit v1.2.3 From 854ea483d4debcbff56c5a5a8e90c3dcce51f350 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 12:40:50 -0600 Subject: util: reformatting and comments --- src/gallium/auxiliary/util/u_blit.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 414cf910254..261a9b6c902 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -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,6 +263,8 @@ setup_vertex_data_tex(struct blit_state *ctx, return offset; } + + /** * Copy pixel block from src surface to dst surface. * Overlapping regions are acceptable. @@ -308,7 +313,9 @@ util_blit_pixels(struct blit_state *ctx, 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) { + 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 */ -- cgit v1.2.3 From 05d393f59fdacbbe181f007efd3054966734b3b7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 13:09:15 -0600 Subject: util: fix util_blit_pixels() test for surface_copy() path For the surface_copy() path require same format, no flipping and no stretching. Fixes progs/tests/copypixrate -blit --- src/gallium/auxiliary/util/u_blit.c | 40 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 261a9b6c902..bc908137193 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -268,6 +268,7 @@ setup_vertex_data_tex(struct blit_state *ctx, /** * Copy pixel block from src surface to dst surface. * Overlapping regions are acceptable. + * Flipping and stretching are supported. * XXX need some control over blitting Z and/or stencil. */ void @@ -294,6 +295,29 @@ util_blit_pixels(struct blit_state *ctx, 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)); + + /* + * Check for simple case: no format conversion, no flipping, no stretching. + */ + if (dst->format == src->format && + srcX0 < srcX1 && + dstX0 < dstX1 && + srcY0 < srcY1 && + dstY0 < dstY1 && + (dstX1 - dstX0) == (srcX1 - srcX0) && + (dstY1 - dstY0) == (srcY1 - srcY0)) { + /* 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; @@ -308,22 +332,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)); -- cgit v1.2.3 From 4f36164024824271eda70348646b1ad1be53e281 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 13:19:01 -0600 Subject: util: added util_blit_pixels() overlap test A comment alluded to this. Now it's checked. --- src/gallium/auxiliary/util/u_blit.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index bc908137193..77573bc0b5e 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -265,6 +265,31 @@ setup_vertex_data_tex(struct blit_state *ctx, } +/** + * \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. @@ -291,6 +316,7 @@ 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); @@ -300,8 +326,13 @@ util_blit_pixels(struct blit_state *ctx, 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. + * Check for simple case: no format conversion, no flipping, no stretching, + * no overlapping. */ if (dst->format == src->format && srcX0 < srcX1 && @@ -309,7 +340,8 @@ util_blit_pixels(struct blit_state *ctx, srcY0 < srcY1 && dstY0 < dstY1 && (dstX1 - dstX0) == (srcX1 - srcX0) && - (dstY1 - dstY0) == (srcY1 - srcY0)) { + (dstY1 - dstY0) == (srcY1 - srcY0) && + !overlap) { /* FIXME: this will most surely fail for overlapping rectangles */ pipe->surface_copy(pipe, dst, dstX0, dstY0, /* dest */ -- cgit v1.2.3 From 727b2d747e13fed78bf62cfbf4a31427eed0ef29 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 13:21:59 -0600 Subject: mesa: make _mesa_clip_blit() a shared function --- src/mesa/main/image.c | 178 +++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/image.h | 6 ++ src/mesa/swrast/s_blit.c | 183 +---------------------------------------------- 3 files changed, 187 insertions(+), 180 deletions(-) (limited to 'src') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 01fbe40a03b..1a4d22256f4 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -5333,3 +5333,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; +} diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h index b26c27e5a8a..ee17accb80c 100644 --- a/src/mesa/main/image.h +++ b/src/mesa/main/image.h @@ -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 diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c index 0e32cb8f653..4a95c222d56 100644 --- a/src/mesa/swrast/s_blit.c +++ b/src/mesa/swrast/s_blit.c @@ -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,8 +570,8 @@ _swrast_BlitFramebuffer(GLcontext *ctx, if (!ctx->DrawBuffer->_NumColorDrawBuffers) return; - if (!clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, - &dstX0, &dstY0, &dstX1, &dstY1)) { + if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, + &dstX0, &dstY0, &dstX1, &dstY1)) { return; } -- cgit v1.2.3 From 2cd33afa0081661b68dd25289f8d904125a9923a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 13:22:26 -0600 Subject: util: added comment/question about blit clipping --- src/gallium/auxiliary/util/u_blit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 77573bc0b5e..f7cc7dd3759 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -294,6 +294,7 @@ regions_overlap(int srcX0, int srcY0, * 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 -- cgit v1.2.3 From f792137593b16b850a8a95dbb4859d49effb9f7c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 13:26:19 -0600 Subject: st/mesa: fix Y inversion and optimize st_BlitFramebuffer() Need to check for Y inversion separately for src/dest buffers. If both the src and dest regions are upside down, make them right-side up for a better chance at a fast path. progs/tests/copypixrate -blit is much faster now. --- src/mesa/state_tracker/st_cb_blit.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 28526234720..98610473b31 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -75,6 +75,11 @@ st_BlitFramebuffer(GLcontext *ctx, ? PIPE_TEX_MIPFILTER_NEAREST : PIPE_TEX_MIPFILTER_LINEAR); + if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, + &dstX0, &dstY0, &dstX1, &dstY1)) { + return; /* nothing to draw/blit */ + } + if (mask & GL_COLOR_BUFFER_BIT) { struct st_renderbuffer *srcRb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); @@ -84,12 +89,29 @@ st_BlitFramebuffer(GLcontext *ctx, struct pipe_surface *dstSurf = dstRb->surface; if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - /* invert Y */ + /* invert Y for dest */ + dstY0 = dstRb->Base.Height - dstY0; + dstY1 = dstRb->Base.Height - dstY1; + } + + if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { + /* invert Y for src */ srcY0 = srcRb->Base.Height - srcY0; srcY1 = srcRb->Base.Height - srcY1; + } - dstY0 = dstRb->Base.Height - dstY0; - dstY1 = dstRb->Base.Height - dstY1; + 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; } util_blit_pixels(st->blit, -- cgit v1.2.3 From dcebe220f430221821a10944fbdb639a9252bfef Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 13:44:59 -0600 Subject: mesa: generate GL_INVALID_OPERATION for missing z/stencil when blitting If glBlitFramebuffer() is called with GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT and the src/dst depth/stencil buffers are absent, report an error. --- src/mesa/main/fbobject.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 83301f1e621..ab91fbc4de9 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -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; -- cgit v1.2.3 From a59579c983df651373435791f8f4fd249293b344 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 Aug 2009 13:46:47 -0600 Subject: st/mesa: implement BlitFramebuffer() for depth/stencil (incomplete) We now handle the case of blitting Z+stencil to/from combined Z/stencil surfaces. But Z-only or stencil-only and separate depth/stencil surfaces are not yet implemented. --- src/mesa/state_tracker/st_cb_blit.c | 109 ++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 98610473b31..c741940bcf4 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -69,56 +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 for dest */ - dstY0 = dstRb->Base.Height - dstY0; - dstY1 = dstRb->Base.Height - dstY1; - } - - if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { - /* invert Y for src */ - srcY0 = srcRb->Base.Height - srcY0; - srcY1 = srcRb->Base.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; - } - 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"); + } + } } } -- cgit v1.2.3