#include "context.h"
#include "fbobject.h"
+#include "texformat.h"
#include "texrender.h"
#include "renderbuffer.h"
*/
struct texture_renderbuffer
{
- struct gl_renderbuffer Base; /* Base class object */
+ struct gl_renderbuffer Base; /**< Base class object */
struct gl_texture_image *TexImage;
StoreTexelFunc Store;
- GLint Zoffset;
+ GLint Yoffset; /**< Layer for 1D array textures. */
+ GLint Zoffset; /**< Layer for 2D array textures, or slice
+ * for 3D textures
+ */
};
ASSERT(trb->TexImage->Width == rb->Width);
ASSERT(trb->TexImage->Height == rb->Height);
+ y += trb->Yoffset;
+
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_SHORT) {
+ GLushort *zValues = (GLushort *) values;
+ for (i = 0; i < count; i++) {
+ GLfloat flt;
+ trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
+ zValues[i] = (GLushort) (flt * 0xffff);
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ GLuint *zValues = (GLuint *) values;
+ /*
+ const GLdouble scale = (GLdouble) 0xffffffff;
+ */
+ for (i = 0; i < count; i++) {
+ GLfloat flt;
+ trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
+#if 0
+ /* this should work, but doesn't (overflow due to low precision) */
+ zValues[i] = (GLuint) (flt * scale);
+#else
+ /* temporary hack */
+ zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
+#endif
+ }
+ }
else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
GLuint *zValues = (GLuint *) values;
for (i = 0; i < count; 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);
+ trb->TexImage->FetchTexelc(trb->TexImage, x[i], y[i] + trb->Yoffset,
+ z, rgbaOut + 4 * i);
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_SHORT) {
+ GLushort *zValues = (GLushort *) values;
+ for (i = 0; i < count; i++) {
+ GLfloat flt;
+ trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+ z, &flt);
+ zValues[i] = (GLushort) (flt * 0xffff);
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ GLuint *zValues = (GLuint *) values;
+ for (i = 0; i < count; i++) {
+ GLfloat flt;
+ trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+ z, &flt);
+#if 0
+ zValues[i] = (GLuint) (flt * 0xffffffff);
+#else
+ zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
+#endif
}
}
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);
+ trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+ z, &flt);
zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
}
}
const GLint z = trb->Zoffset;
GLuint i;
+ y += trb->Yoffset;
+
if (rb->DataType == CHAN_TYPE) {
const GLchan *rgba = (const GLchan *) values;
for (i = 0; i < count; i++) {
rgba += 4;
}
}
+ else if (rb->DataType == GL_UNSIGNED_SHORT) {
+ const GLushort *zValues = (const GLushort *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, zValues + i);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ const GLuint *zValues = (const GLuint *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, zValues + i);
+ }
+ }
+ }
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);
+ GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
+ trb->Store(trb->TexImage, x + i, y, z, &flt);
+ }
+ }
+ }
+ else {
+ _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");
+ }
+}
+
+/**
+ * Put row of RGB values into a renderbuffer that wraps a texture image.
+ */
+static void
+texture_put_row_rgb(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+ GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+ const struct texture_renderbuffer *trb
+ = (const struct texture_renderbuffer *) rb;
+ const GLint z = trb->Zoffset;
+ GLuint i;
+
+ y += trb->Yoffset;
+
+ if (rb->DataType == CHAN_TYPE) {
+ const GLchan *rgb = (const GLchan *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, rgb);
+ }
+ rgb += 3;
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_SHORT) {
+ const GLushort *zValues = (const GLushort *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, zValues + i);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ const GLuint *zValues = (const GLuint *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, zValues + i);
+ }
+ }
+ }
+ 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 = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
trb->Store(trb->TexImage, x + i, y, z, &flt);
}
}
const GLint z = trb->Zoffset;
GLuint i;
+ y += trb->Yoffset;
+
if (rb->DataType == CHAN_TYPE) {
const GLchan *rgba = (const GLchan *) value;
for (i = 0; i < count; i++) {
}
}
}
+ else if (rb->DataType == GL_UNSIGNED_SHORT) {
+ const GLushort zValue = *((const GLushort *) value);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, &zValue);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ const GLuint zValue = *((const GLuint *) value);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x + i, y, z, &zValue);
+ }
+ }
+ }
else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
const GLuint zValue = *((const GLuint *) value);
- const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff);
+ const GLfloat flt = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff));
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
trb->Store(trb->TexImage, x + i, y, z, &flt);
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);
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);
}
rgba += 4;
}
}
+ else if (rb->DataType == GL_UNSIGNED_SHORT) {
+ const GLushort *zValues = (const GLushort *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ const GLuint *zValues = (const GLuint *) values;
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i);
+ }
+ }
+ }
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);
+ GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff));
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
}
}
}
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);
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_INT) {
+ const GLuint zValue = *((const GLuint *) value);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue);
+ }
+ }
+ }
+ else if (rb->DataType == GL_UNSIGNED_SHORT) {
+ const GLushort zValue = *((const GLushort *) value);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue);
}
}
}
else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {
const GLuint zValue = *((const GLuint *) value);
- const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff);
+ const GLfloat flt = (GLfloat) ((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);
+ trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);
}
}
}
}
+static void
+store_nop(struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ const void *texel)
+{
+}
+
+
static void
delete_texture_wrapper(struct gl_renderbuffer *rb)
{
trb->Base.GetRow = texture_get_row;
trb->Base.GetValues = texture_get_values;
trb->Base.PutRow = texture_put_row;
+ trb->Base.PutRowRGB = texture_put_row_rgb;
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);
+ _mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base));
}
{
struct texture_renderbuffer *trb
= (struct texture_renderbuffer *) att->Renderbuffer;
+ gl_format texFormat;
+ (void) ctx;
ASSERT(trb);
trb->TexImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
ASSERT(trb->TexImage);
- trb->Store = trb->TexImage->TexFormat->StoreTexel;
- ASSERT(trb->Store);
+ trb->Store = _mesa_get_texel_store_func(trb->TexImage->TexFormat);
+ if (!trb->Store) {
+ /* we'll never draw into some textures (compressed formats) */
+ trb->Store = store_nop;
+ }
+
+ if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
+ trb->Yoffset = att->Zoffset;
+ trb->Zoffset = 0;
+ }
+ else {
+ trb->Yoffset = 0;
+ trb->Zoffset = att->Zoffset;
+ }
- trb->Zoffset = att->Zoffset;
+ texFormat = trb->TexImage->TexFormat;
trb->Base.Width = trb->TexImage->Width;
trb->Base.Height = trb->TexImage->Height;
trb->Base.InternalFormat = trb->TexImage->InternalFormat;
/* XXX may need more special cases here */
- if (trb->TexImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ if (trb->TexImage->TexFormat == MESA_FORMAT_Z24_S8) {
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) {
+ else if (trb->TexImage->TexFormat == MESA_FORMAT_Z16) {
+ trb->Base._ActualFormat = GL_DEPTH_COMPONENT;
+ trb->Base.DataType = GL_UNSIGNED_SHORT;
+ }
+ else if (trb->TexImage->TexFormat == MESA_FORMAT_Z32) {
trb->Base._ActualFormat = GL_DEPTH_COMPONENT;
- trb->Base.DataType = GL_FLOAT;
+ trb->Base.DataType = GL_UNSIGNED_INT;
}
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 ||
- trb->Base._BaseFormat == GL_RGBA ||
- trb->Base._BaseFormat == GL_DEPTH_COMPONENT);
-#endif
+ trb->Base._BaseFormat = trb->TexImage->_BaseFormat;
trb->Base.Data = trb->TexImage->Data;
- 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;
+ trb->Base.RedBits = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE);
+ trb->Base.GreenBits = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE);
+ trb->Base.BlueBits = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE);
+ trb->Base.AlphaBits = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE);
+ trb->Base.DepthBits = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE_ARB);
+ trb->Base.StencilBits = _mesa_get_format_bits(texFormat, GL_TEXTURE_STENCIL_SIZE_EXT);
}
struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att)
{
+ (void) fb;
+
if (!att->Renderbuffer) {
wrap_texture(ctx, att);
}
/* The renderbuffer texture wrapper will get deleted by the
* normal mechanism for deleting renderbuffers.
*/
+ (void) ctx;
+ (void) att;
}