|
|
@@ -309,6 +309,8 @@ _mesa_base_format(GLenum format) |
|
|
|
switch (format) { |
|
|
|
case GL_DEPTH_COMPONENT: |
|
|
|
return GL_DEPTH_COMPONENT; |
|
|
|
case GL_DEPTH_STENCIL: |
|
|
|
return GL_DEPTH_STENCIL; |
|
|
|
case GL_STENCIL_INDEX: |
|
|
|
return GL_STENCIL_INDEX; |
|
|
|
default: |
|
|
@@ -617,7 +619,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, |
|
|
|
|
|
|
|
static void |
|
|
|
draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, |
|
|
|
GLsizei width, GLsizei height, GLenum type, |
|
|
|
GLsizei width, GLsizei height, GLenum format, GLenum type, |
|
|
|
const struct gl_pixelstore_attrib *unpack, |
|
|
|
const GLvoid *pixels) |
|
|
|
{ |
|
|
@@ -634,6 +636,11 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, |
|
|
|
|
|
|
|
strb = st_renderbuffer(ctx->DrawBuffer-> |
|
|
|
Attachment[BUFFER_STENCIL].Renderbuffer); |
|
|
|
|
|
|
|
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { |
|
|
|
y = ctx->DrawBuffer->Height - y - height; |
|
|
|
} |
|
|
|
|
|
|
|
pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, |
|
|
|
PIPE_TRANSFER_WRITE, x, y, |
|
|
|
width, height); |
|
|
@@ -650,53 +657,74 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, |
|
|
|
const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); |
|
|
|
GLint row; |
|
|
|
for (row = 0; row < height; row++) { |
|
|
|
GLint spanY = row; |
|
|
|
GLubyte values[MAX_WIDTH]; |
|
|
|
GLubyte sValues[MAX_WIDTH]; |
|
|
|
GLuint zValues[MAX_WIDTH]; |
|
|
|
GLenum destType = GL_UNSIGNED_BYTE; |
|
|
|
const GLvoid *source = _mesa_image_address2d(unpack, pixels, |
|
|
|
width, height, |
|
|
|
GL_COLOR_INDEX, type, |
|
|
|
format, type, |
|
|
|
row, skipPixels); |
|
|
|
_mesa_unpack_stencil_span(ctx, spanWidth, destType, values, |
|
|
|
_mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues, |
|
|
|
type, source, unpack, |
|
|
|
ctx->_ImageTransferState); |
|
|
|
|
|
|
|
if (format == GL_DEPTH_STENCIL) { |
|
|
|
_mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues, |
|
|
|
(1 << 24) - 1, type, source, unpack); |
|
|
|
} |
|
|
|
|
|
|
|
if (zoom) { |
|
|
|
/* |
|
|
|
_swrast_write_zoomed_stencil_span(ctx, 0, 0, spanWidth, |
|
|
|
spanX, spanY, values); |
|
|
|
*/ |
|
|
|
_mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with " |
|
|
|
"zoom not complete"); |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
{ |
|
|
|
GLint spanY; |
|
|
|
|
|
|
|
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { |
|
|
|
spanY = height - spanY - 1; |
|
|
|
spanY = height - row - 1; |
|
|
|
} |
|
|
|
else { |
|
|
|
spanY = row; |
|
|
|
} |
|
|
|
|
|
|
|
/* now pack the stencil (and Z) values in the dest format */ |
|
|
|
switch (pt->format) { |
|
|
|
case PIPE_FORMAT_S8_UNORM: |
|
|
|
{ |
|
|
|
ubyte *dest = stmap + spanY * pt->stride + spanX; |
|
|
|
memcpy(dest, values, spanWidth); |
|
|
|
memcpy(dest, sValues, spanWidth); |
|
|
|
} |
|
|
|
break; |
|
|
|
case PIPE_FORMAT_S8Z24_UNORM: |
|
|
|
{ |
|
|
|
if (format == GL_DEPTH_STENCIL) { |
|
|
|
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); |
|
|
|
GLint k; |
|
|
|
for (k = 0; k < spanWidth; k++) { |
|
|
|
dest[k] = zValues[k] | (sValues[k] << 24); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); |
|
|
|
GLint k; |
|
|
|
for (k = 0; k < spanWidth; k++) { |
|
|
|
uint p = dest[k]; |
|
|
|
p = (p & 0xffffff) | (values[k] << 24); |
|
|
|
dest[k] = p; |
|
|
|
dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
case PIPE_FORMAT_Z24S8_UNORM: |
|
|
|
{ |
|
|
|
if (format == GL_DEPTH_STENCIL) { |
|
|
|
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); |
|
|
|
GLint k; |
|
|
|
for (k = 0; k < spanWidth; k++) { |
|
|
|
uint p = dest[k]; |
|
|
|
p = (p & 0xffffff00) | (values[k] & 0xff); |
|
|
|
dest[k] = p; |
|
|
|
dest[k] = zValues[k] | (sValues[k] << 24); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); |
|
|
|
GLint k; |
|
|
|
for (k = 0; k < spanWidth; k++) { |
|
|
|
dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
@@ -731,8 +759,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, |
|
|
|
GLuint bufferFormat; |
|
|
|
const GLfloat *color; |
|
|
|
|
|
|
|
if (format == GL_STENCIL_INDEX) { |
|
|
|
draw_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels); |
|
|
|
if (format == GL_STENCIL_INDEX || |
|
|
|
format == GL_DEPTH_STENCIL) { |
|
|
|
draw_stencil_pixels(ctx, x, y, width, height, format, type, |
|
|
|
unpack, pixels); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
@@ -747,11 +777,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, |
|
|
|
stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE); |
|
|
|
color = ctx->Current.RasterColor; |
|
|
|
} |
|
|
|
else if (format == GL_STENCIL_INDEX) { |
|
|
|
ps = st->state.framebuffer.zsbuf; |
|
|
|
/* XXX special case - can't use texture map */ |
|
|
|
color = NULL; |
|
|
|
} |
|
|
|
else { |
|
|
|
ps = st->state.framebuffer.cbufs[0]; |
|
|
|
stfp = combined_drawpix_fragment_program(ctx); |
|
|
@@ -797,7 +822,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, |
|
|
|
} |
|
|
|
|
|
|
|
/* this will do stencil pixel transfer ops */ |
|
|
|
st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE, |
|
|
|
st_read_stencil_pixels(ctx, srcx, srcy, width, height, |
|
|
|
GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, |
|
|
|
&ctx->DefaultPacking, buffer); |
|
|
|
|
|
|
|
ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0, |