diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2006-03-29 04:51:03 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2006-03-29 04:51:03 +0000 | 
| commit | 555478fed6240db06db364716d40ccfd235b466b (patch) | |
| tree | 4a21df68fc50444f1506c9eefcd9aaafb15ea4f7 | |
| parent | 2742c4e4db63d61f585c014103eaeadffa8e0833 (diff) | |
New code for rendering to depth/stencil textures.
Re-org of the renderbuffer wrapper code.
| -rw-r--r-- | src/mesa/main/texrender.c | 246 | 
1 files changed, 178 insertions, 68 deletions
| diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c index 85565bfb1d..db720cef6e 100644 --- a/src/mesa/main/texrender.c +++ b/src/mesa/main/texrender.c @@ -22,7 +22,9 @@ struct texture_renderbuffer  }; - +/** + * Get row of values from the renderbuffer that wraps a texture image. + */  static void  texture_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                  GLint x, GLint y, void *values) @@ -30,13 +32,31 @@ texture_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,     const struct texture_renderbuffer *trb        = (const struct texture_renderbuffer *) rb;     const GLint z = trb->Zoffset; -   GLchan *rgbaOut = (GLchan *) values;     GLuint i; -   for (i = 0; i < count; i++) { -      trb->TexImage->FetchTexelc(trb->TexImage, x + i, y, z, rgbaOut + 4 * i); + +   ASSERT(trb->TexImage->Width == rb->Width); +   ASSERT(trb->TexImage->Height == rb->Height); + +   if (rb->DataType == CHAN_TYPE) { +      GLchan *rgbaOut = (GLchan *) values; +      for (i = 0; i < count; i++) { +         trb->TexImage->FetchTexelc(trb->TexImage, x + i, y, z, rgbaOut + 4 * i); +      } +   } +   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { +      GLuint *zValues = (GLuint *) values; +      for (i = 0; i < count; i++) { +         GLfloat flt; +         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt); +         zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; +      } +   } +   else { +      _mesa_problem(ctx, "invalid rb->DataType in texture_get_row");     }  } +  static void  texture_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                     const GLint x[], const GLint y[], void *values) @@ -44,14 +64,32 @@ texture_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,     const struct texture_renderbuffer *trb        = (const struct texture_renderbuffer *) rb;     const GLint z = trb->Zoffset; -   GLchan *rgbaOut = (GLchan *) values;     GLuint i; -   for (i = 0; i < count; i++) { -      trb->TexImage->FetchTexelc(trb->TexImage, x[i], y[i], z, -                                 rgbaOut + 4 * i); + +   if (rb->DataType == CHAN_TYPE) { +      GLchan *rgbaOut = (GLchan *) values; +      for (i = 0; i < count; i++) { +         trb->TexImage->FetchTexelc(trb->TexImage, x[i], y[i], z, +                                    rgbaOut + 4 * i); +      } +   } +   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { +      GLuint *zValues = (GLuint *) values; +      for (i = 0; i < count; i++) { +         GLfloat flt; +         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i], z, &flt); +         zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; +      } +   } +   else { +      _mesa_problem(ctx, "invalid rb->DataType in texture_get_values");     }  } + +/** + * Put row of values into a renderbuffer that wraps a texture image. + */  static void  texture_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                  GLint x, GLint y, const void *values, const GLubyte *mask) @@ -59,16 +97,32 @@ texture_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,     const struct texture_renderbuffer *trb        = (const struct texture_renderbuffer *) rb;     const GLint z = trb->Zoffset; -   const GLchan *rgba = (const GLchan *) values;     GLuint i; -   for (i = 0; i < count; i++) { -      if (!mask || mask[i]) { -         trb->Store(trb->TexImage, x + i, y, z, rgba); + +   if (rb->DataType == CHAN_TYPE) { +      const GLchan *rgba = (const GLchan *) values; +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            trb->Store(trb->TexImage, x + i, y, z, rgba); +         } +         rgba += 4; +      } +   } +   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { +      const GLuint *zValues = (const GLuint *) values; +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            GLfloat flt = (zValues[i] >> 8) * (1.0 / 0xffffff); +            trb->Store(trb->TexImage, x + i, y, z, &flt); +         }        } -      rgba += 4; +   } +   else { +      _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");     }  } +  static void  texture_put_mono_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                       GLint x, GLint y, const void *value, const GLubyte *mask) @@ -76,15 +130,31 @@ texture_put_mono_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,     const struct texture_renderbuffer *trb        = (const struct texture_renderbuffer *) rb;     const GLint z = trb->Zoffset; -   const GLchan *rgba = (const GLchan *) value;     GLuint i; -   for (i = 0; i < count; i++) { -      if (!mask || mask[i]) { -         trb->Store(trb->TexImage, x + i, y, z, rgba); + +   if (rb->DataType == CHAN_TYPE) { +      const GLchan *rgba = (const GLchan *) value; +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            trb->Store(trb->TexImage, x + i, y, z, rgba); +         } +      } +   } +   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { +      const GLuint zValue = *((const GLuint *) value); +      const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff); +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            trb->Store(trb->TexImage, x + i, y, z, &flt); +         }        }     } +   else { +      _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_row"); +   }  } +  static void  texture_put_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                     const GLint x[], const GLint y[], const void *values, @@ -93,16 +163,32 @@ texture_put_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,     const struct texture_renderbuffer *trb        = (const struct texture_renderbuffer *) rb;     const GLint z = trb->Zoffset; -   const GLchan *rgba = (const GLchan *) values;     GLuint i; -   for (i = 0; i < count; i++) { -      if (!mask || mask[i]) { -         trb->Store(trb->TexImage, x[i], y[i], z, rgba); + +   if (rb->DataType == CHAN_TYPE) { +      const GLchan *rgba = (const GLchan *) values; +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            trb->Store(trb->TexImage, x[i], y[i], z, rgba); +         } +         rgba += 4; +      } +   } +   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { +      const GLuint *zValues = (const GLuint *) values; +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            GLfloat flt = (zValues[i] >> 8) * (1.0 / 0xffffff); +            trb->Store(trb->TexImage, x[i], y[i], z, &flt); +         }        } -      rgba += 4; +   } +   else { +      _mesa_problem(ctx, "invalid rb->DataType in texture_put_values");     }  } +  static void  texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb,                          GLuint count, const GLint x[], const GLint y[], @@ -111,13 +197,28 @@ texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb,     const struct texture_renderbuffer *trb        = (const struct texture_renderbuffer *) rb;     const GLint z = trb->Zoffset; -   const GLchan *rgba = (const GLchan *) value;     GLuint i; -   for (i = 0; i < count; i++) { -      if (!mask || mask[i]) { -         trb->Store(trb->TexImage, x[i], y[i], z, rgba); + +   if (rb->DataType == CHAN_TYPE) { +      const GLchan *rgba = (const GLchan *) value; +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            trb->Store(trb->TexImage, x[i], y[i], z, rgba); +         } +      } +   } +   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { +      const GLuint zValue = *((const GLuint *) value); +      const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff); +      for (i = 0; i < count; i++) { +         if (!mask || mask[i]) { +            trb->Store(trb->TexImage, x[i], y[i], z, &flt); +         }        }     } +   else { +      _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_values"); +   }  } @@ -130,10 +231,9 @@ delete_texture_wrapper(struct gl_renderbuffer *rb)  /** - * If a render buffer attachment specifies a texture image, we'll use - * this function to make a gl_renderbuffer wrapper around the texture image. - * This allows other parts of Mesa to access the texture image as if it - * was a renderbuffer. + * This function creates a renderbuffer object which wraps a texture image. + * The new renderbuffer is plugged into the given attachment point. + * This allows rendering into the texture as if it were a renderbuffer.   */  static void  wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att) @@ -143,9 +243,6 @@ wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)     ASSERT(att->Type == GL_TEXTURE);     ASSERT(att->Renderbuffer == NULL); -   /* -   ASSERT(att->Complete); -   */     trb = CALLOC_STRUCT(texture_renderbuffer);     if (!trb) { @@ -153,48 +250,75 @@ wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att)        return;     } +   /* init base gl_renderbuffer fields */     _mesa_init_renderbuffer(&trb->Base, name); +   /* plug in our texture_renderbuffer-specific functions */ +   trb->Base.Delete = delete_texture_wrapper; +   trb->Base.AllocStorage = NULL; /* illegal! */ +   trb->Base.GetRow = texture_get_row; +   trb->Base.GetValues = texture_get_values; +   trb->Base.PutRow = texture_put_row; +   trb->Base.PutMonoRow = texture_put_mono_row; +   trb->Base.PutValues = texture_put_values; +   trb->Base.PutMonoValues = texture_put_mono_values; + +   /* update attachment point */ +   att->Renderbuffer = &(trb->Base); +} + + + +/** + * Update the renderbuffer wrapper for rendering to a texture. + * For example, update the width, height of the RB based on the texture size, + * update the internal format info, etc. + */ +static void +update_wrapper(GLcontext *ctx, const struct gl_renderbuffer_attachment *att) +{ +   struct texture_renderbuffer *trb +      = (struct texture_renderbuffer *) att->Renderbuffer; + +   ASSERT(trb);     trb->TexImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; -   assert(trb->TexImage); +   ASSERT(trb->TexImage);     trb->Store = trb->TexImage->TexFormat->StoreTexel; -   assert(trb->Store); +   ASSERT(trb->Store);     trb->Zoffset = att->Zoffset;     trb->Base.Width = trb->TexImage->Width;     trb->Base.Height = trb->TexImage->Height; -   trb->Base.InternalFormat = trb->TexImage->InternalFormat; /* XXX fix? */ +   trb->Base.InternalFormat = trb->TexImage->InternalFormat; +   /* XXX may need more special cases here */ +   if (trb->TexImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) { +      trb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; +      trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; +   } +   else if (trb->TexImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) { +      trb->Base._ActualFormat = GL_DEPTH_COMPONENT; +      trb->Base.DataType = GL_FLOAT; +   } +   else { +      trb->Base._ActualFormat = trb->TexImage->InternalFormat; +      trb->Base.DataType = CHAN_TYPE; +   }     trb->Base._BaseFormat = trb->TexImage->TexFormat->BaseFormat;  #if 0     /* fix/avoid this assertion someday */ -   assert(trb->Base._BaseFormat == GL_RGB || +   ASSERT(trb->Base._BaseFormat == GL_RGB ||            trb->Base._BaseFormat == GL_RGBA ||            trb->Base._BaseFormat == GL_DEPTH_COMPONENT);  #endif -   trb->Base.DataType = GL_UNSIGNED_BYTE;  /* XXX fix! */     trb->Base.Data = trb->TexImage->Data; -   trb->Base.GetRow = texture_get_row; -   trb->Base.GetValues = texture_get_values; -   trb->Base.PutRow = texture_put_row; -   trb->Base.PutMonoRow = texture_put_mono_row; -   trb->Base.PutValues = texture_put_values; -   trb->Base.PutMonoValues = texture_put_mono_values; - -   trb->Base.Delete = delete_texture_wrapper; -   trb->Base.AllocStorage = NULL; /* illegal! */ - -   /* XXX fix these */     trb->Base.RedBits = trb->TexImage->TexFormat->RedBits;     trb->Base.GreenBits = trb->TexImage->TexFormat->GreenBits;     trb->Base.BlueBits = trb->TexImage->TexFormat->BlueBits;     trb->Base.AlphaBits = trb->TexImage->TexFormat->AlphaBits;     trb->Base.DepthBits = trb->TexImage->TexFormat->DepthBits; - -   att->Renderbuffer = &(trb->Base); -   trb->Base.RefCount++;  } @@ -221,24 +345,10 @@ _mesa_render_texture(GLcontext *ctx,                       struct gl_framebuffer *fb,                       struct gl_renderbuffer_attachment *att)  { -   struct gl_texture_image *newImage -      = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; -   struct texture_renderbuffer *trb -      = (struct texture_renderbuffer *) att->Renderbuffer; -   struct gl_texture_image *oldImage = trb ? trb->TexImage : NULL; - -   (void) fb; - -   ASSERT(newImage); - -   if (oldImage != newImage) { -      if (trb) { -         /* get rid of old wrapper */ -         /* XXX also if Zoffset changes? */ -         trb->Base.Delete(&trb->Base); -      } +   if (!att->Renderbuffer) {        wrap_texture(ctx, att);     } +   update_wrapper(ctx, att);  } | 
