summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-10-13 12:28:53 -0600
committerBrian <[email protected]>2007-10-13 12:28:53 -0600
commitfa1d442879f1279cf510a52a1002367b904d35ad (patch)
treeb3bf5f2bf58fecb29ebdf14ee285d9d3ce134e41
parent12f41c8884616b8b0c0e445a8bd3f0587a970d1a (diff)
GL_STENCIL_INDEX support
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c85
1 files changed, 83 insertions, 2 deletions
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 15abc8550be..92705cdc441 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -32,6 +32,7 @@
#include "main/imports.h"
#include "main/image.h"
+#include "main/macros.h"
#include "st_context.h"
#include "st_atom.h"
@@ -720,6 +721,81 @@ draw_blit(struct st_context *st,
}
+static void
+draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+ struct st_context *st = ctx->st;
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_surface *ps = st->state.framebuffer.sbuf;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
+ GLint skipPixels;
+ ubyte *stmap;
+
+ /* map the stencil buffer */
+ stmap = pipe->region_map(pipe, ps->region);
+
+ /* if width > MAX_WIDTH, have to process image in chunks */
+ skipPixels = 0;
+ while (skipPixels < width) {
+ const GLint spanX = x + skipPixels;
+ const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLint spanY = y + row;
+ GLubyte values[MAX_WIDTH];
+ GLenum destType = GL_UNSIGNED_BYTE;
+ const GLvoid *source = _mesa_image_address2d(unpack, pixels,
+ width, height,
+ GL_COLOR_INDEX, type,
+ row, skipPixels);
+ _mesa_unpack_stencil_span(ctx, spanWidth, destType, values,
+ type, source, unpack,
+ ctx->_ImageTransferState);
+ if (zoom) {
+ /*
+ _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth,
+ spanX, spanY, values);
+ */
+ }
+ else {
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+ spanY = ctx->DrawBuffer->Height - spanY - 1;
+ }
+
+ switch (ps->format) {
+ case PIPE_FORMAT_U_S8:
+ {
+ ubyte *dest = stmap + spanY * ps->region->pitch + spanX;
+ memcpy(dest, values, spanWidth);
+ }
+ break;
+ case PIPE_FORMAT_S8_Z24:
+ {
+ uint *dest = (uint *) stmap + spanY * ps->region->pitch + spanX;
+ GLint k;
+ for (k = 0; k < spanWidth; k++) {
+ uint p = dest[k];
+ p = (p & 0xffffff) | (values[k] << 24);
+ dest[k] = p;
+ }
+ }
+ break;
+ default:
+ assert(0);
+ }
+ }
+ }
+ skipPixels += spanWidth;
+ }
+
+ /* unmap the stencil buffer */
+ pipe->region_unmap(pipe, ps->region);
+}
+
+
/**
* Called via ctx->Driver.DrawPixels()
*/
@@ -739,7 +815,12 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
GLuint bufferFormat;
const GLfloat *color;
- /* create the fragment program if needed */
+ if (format == GL_STENCIL_INDEX) {
+ draw_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels);
+ return;
+ }
+
+ /* create the fragment programs if needed */
if (!stfp_c) {
stfp_c = make_fragment_shader(ctx->st, GL_FALSE);
}
@@ -747,7 +828,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
stfp_z = make_fragment_shader_z(ctx->st);
}
- /* and vertex program */
+ /* and vertex programs */
if (!stvp_t) {
stvp_t = make_vertex_shader(ctx->st, GL_FALSE);
}