浏览代码

st: implement GL_DEPTH_STENCIL format for glReadPixels and DrawPixels()

tags/mesa_7_5_rc1
Brian Paul 16 年前
父节点
当前提交
b7615e5240

+ 54
- 28
src/mesa/state_tracker/st_cb_drawpixels.c 查看文件

@@ -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,

+ 40
- 14
src/mesa/state_tracker/st_cb_readpixels.c 查看文件

@@ -56,7 +56,8 @@
*/
void
st_read_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 *packing,
GLvoid *pixels)
{
@@ -84,7 +85,8 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
/* process image row by row */
for (j = 0; j < height; j++) {
GLvoid *dest;
GLstencil values[MAX_WIDTH];
GLstencil sValues[MAX_WIDTH];
GLfloat zValues[MAX_WIDTH];
GLint srcY;

if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
@@ -94,29 +96,47 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
srcY = j;
}

/* get stencil values */
/* get stencil (and Z) values */
switch (pt->format) {
case PIPE_FORMAT_S8_UNORM:
{
const ubyte *src = stmap + srcY * pt->stride;
memcpy(values, src, width);
memcpy(sValues, src, width);
}
break;
case PIPE_FORMAT_S8Z24_UNORM:
{
if (format == GL_DEPTH_STENCIL) {
const uint *src = (uint *) (stmap + srcY * pt->stride);
const GLfloat scale = 1.0 / (0xffffff);
GLint k;
for (k = 0; k < width; k++) {
sValues[k] = src[k] >> 24;
zValues[k] = (src[k] & 0xffffff) * scale;
}
}
else {
const uint *src = (uint *) (stmap + srcY * pt->stride);
GLint k;
for (k = 0; k < width; k++) {
values[k] = src[k] >> 24;
sValues[k] = src[k] >> 24;
}
}
break;
case PIPE_FORMAT_Z24S8_UNORM:
{
if (format == GL_DEPTH_STENCIL) {
const uint *src = (uint *) (stmap + srcY * pt->stride);
const GLfloat scale = 1.0 / (0xffffff);
GLint k;
for (k = 0; k < width; k++) {
values[k] = src[k] & 0xff;
sValues[k] = src[k] & 0xff;
zValues[k] = (src[k] >> 8) * scale;
}
}
else {
const uint *src = (uint *) (stmap + srcY * pt->stride);
GLint k;
for (k = 0; k < width; k++) {
sValues[k] = src[k] & 0xff;
}
}
break;
@@ -126,12 +146,16 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,

/* store */
dest = _mesa_image_address2d(packing, pixels, width, height,
GL_STENCIL_INDEX, type, j, 0);

_mesa_pack_stencil_span(ctx, width, type, dest, values, packing);
format, type, j, 0);
if (format == GL_DEPTH_STENCIL) {
_mesa_pack_depth_stencil_span(ctx, width, dest,
zValues, sValues, packing);
}
else {
_mesa_pack_stencil_span(ctx, width, type, dest, sValues, packing);
}
}


/* unmap the stencil buffer */
screen->transfer_unmap(screen, pt);
screen->tex_transfer_destroy(pt);
@@ -329,8 +353,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
/* make sure rendering has completed */
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);

if (format == GL_STENCIL_INDEX) {
st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest);
if (format == GL_STENCIL_INDEX ||
format == GL_DEPTH_STENCIL) {
st_read_stencil_pixels(ctx, x, y, width, height,
format, type, pack, dest);
return;
}
else if (format == GL_DEPTH_COMPONENT) {

+ 2
- 1
src/mesa/state_tracker/st_cb_readpixels.h 查看文件

@@ -34,7 +34,8 @@ st_get_color_read_renderbuffer(GLcontext *ctx);

extern void
st_read_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 *packing,
GLvoid *pixels);


正在加载...
取消
保存