summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-07-09 05:08:36 +0200
committerMarek Olšák <[email protected]>2012-07-12 02:08:30 +0200
commit5ba15d8d38d98cb7b625fa55e7d818ef9c6629ce (patch)
tree66b9f598baf5f16cc003f55bc118c840ab36bd90 /src/mesa/state_tracker
parenta7f3697eb849376dda23556df479127909cb7fd4 (diff)
st/mesa: implement accelerated stencil blitting using shader stencil export
Reviewed-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c37
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c12
-rw-r--r--src/mesa/state_tracker/st_context.c2
-rw-r--r--src/mesa/state_tracker/st_context.h2
4 files changed, 41 insertions, 12 deletions
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index a50b79a1852..1486779fd9f 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -242,7 +242,7 @@ st_BlitFramebuffer(struct gl_context *ctx,
srcX0, srcY0, srcX1, srcY1,
srcAtt->Zoffset + srcAtt->CubeMapFace,
dstSurf, dstX0, dstY0, dstX1, dstY1,
- 0.0, pFilter, TGSI_WRITEMASK_XYZW);
+ 0.0, pFilter, TGSI_WRITEMASK_XYZW, 0);
}
else {
struct st_renderbuffer *srcRb =
@@ -257,7 +257,7 @@ st_BlitFramebuffer(struct gl_context *ctx,
srcX0, srcY0, srcX1, srcY1,
srcSurf->u.tex.first_layer,
dstSurf, dstX0, dstY0, dstX1, dstY1,
- 0.0, pFilter, TGSI_WRITEMASK_XYZW);
+ 0.0, pFilter, TGSI_WRITEMASK_XYZW, 0);
}
}
@@ -281,6 +281,13 @@ st_BlitFramebuffer(struct gl_context *ctx,
struct pipe_surface *dstDepthSurf =
dstDepthRb ? dstDepthRb->surface : NULL;
+ 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 *dstStencilSurf =
+ dstStencilRb ? dstStencilRb->surface : NULL;
+
if ((mask & depthStencil) == depthStencil &&
st_is_depth_stencil_combined(srcDepth, srcStencil) &&
st_is_depth_stencil_combined(dstDepth, dstStencil)) {
@@ -294,7 +301,15 @@ st_BlitFramebuffer(struct gl_context *ctx,
srcX0, srcY0, srcX1, srcY1,
srcDepthRb->surface->u.tex.first_layer,
dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
- 0.0, pFilter, 0);
+ 0.0, pFilter, 0,
+ BLIT_WRITEMASK_Z |
+ (st->has_stencil_export ? BLIT_WRITEMASK_STENCIL
+ : 0));
+
+ if (!st->has_stencil_export) {
+ _mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) "
+ "software fallback not implemented");
+ }
}
else {
/* blitting depth and stencil separately */
@@ -305,12 +320,22 @@ st_BlitFramebuffer(struct gl_context *ctx,
srcX0, srcY0, srcX1, srcY1,
srcDepthRb->surface->u.tex.first_layer,
dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
- 0.0, pFilter, 0);
+ 0.0, pFilter, 0, BLIT_WRITEMASK_Z);
}
if (mask & GL_STENCIL_BUFFER_BIT) {
- /* blit stencil only */
- _mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) not completed");
+ if (st->has_stencil_export) {
+ util_blit_pixels(st->blit, srcStencilRb->texture,
+ srcStencilRb->surface->u.tex.level,
+ srcX0, srcY0, srcX1, srcY1,
+ srcStencilRb->surface->u.tex.first_layer,
+ dstStencilSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter, 0, BLIT_WRITEMASK_STENCIL);
+ }
+ else {
+ _mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) "
+ "software fallback not implemented");
+ }
}
}
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index a1d6951c1a2..a7f57b96f27 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -944,7 +944,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
struct pipe_screen *screen = pipe->screen;
enum pipe_format dest_format, src_format;
GLboolean matching_base_formats;
- GLuint format_writemask, sample_count;
+ GLuint color_writemask, zs_writemask, sample_count;
struct pipe_surface *dest_surface = NULL;
GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
struct pipe_surface surf_tmpl;
@@ -1025,15 +1025,17 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
}
if (texBaseFormat == GL_DEPTH_COMPONENT) {
- format_writemask = TGSI_WRITEMASK_XYZW;
+ color_writemask = 0;
+ zs_writemask = BLIT_WRITEMASK_Z;
dst_usage = PIPE_BIND_DEPTH_STENCIL;
}
else {
- format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage);
+ color_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage);
+ zs_writemask = 0;
dst_usage = PIPE_BIND_RENDER_TARGET;
}
- if (!format_writemask ||
+ if ((!color_writemask && !zs_writemask) ||
!screen->is_format_supported(screen, src_format,
PIPE_TEXTURE_2D, sample_count,
PIPE_BIND_SAMPLER_VIEW) ||
@@ -1076,7 +1078,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
destX, destY,
destX + width, destY + height,
0.0, PIPE_TEX_MIPFILTER_NEAREST,
- format_writemask);
+ color_writemask, zs_writemask);
pipe_surface_reference(&dest_surface, NULL);
/* Restore conditional rendering state. */
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 132dcc02f96..117ea90f80d 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -187,6 +187,8 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
st->pixel_xfer.cache = _mesa_new_program_cache();
st->force_msaa = st_get_msaa();
+ st->has_stencil_export =
+ screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
/* GL limits and extensions */
st_init_limits(st);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 734b4d9c173..a3f44b3aba4 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -81,7 +81,7 @@ struct st_context
struct draw_stage *rastpos_stage; /**< For glRasterPos */
GLboolean clamp_frag_color_in_shader;
GLboolean clamp_vert_color_in_shader;
-
+ boolean has_stencil_export; /**< can do shader stencil export? */
/* On old libGL's for linux we need to invalidate the drawables
* on glViewpport calls, this is set via a option.