X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_texrender.c;h=d67e48ad36c04e55d64dc13de81c96cc102cf03a;hb=5a4e0f3873657d874eb5ff52819f42ea38d54b91;hp=52d03c92ac710c9216911f8c4bccd80be374992f;hpb=c3b2230b71cb3a00a7f4c0987197d397bada650b;p=mesa.git diff --git a/src/mesa/swrast/s_texrender.c b/src/mesa/swrast/s_texrender.c index 52d03c92ac7..d67e48ad36c 100644 --- a/src/mesa/swrast/s_texrender.c +++ b/src/mesa/swrast/s_texrender.c @@ -3,10 +3,11 @@ #include "main/colormac.h" #include "main/fbobject.h" #include "main/macros.h" -#include "main/texfetch.h" #include "main/teximage.h" #include "main/renderbuffer.h" #include "swrast/swrast.h" +#include "swrast/s_context.h" +#include "swrast/s_texfetch.h" /* @@ -14,512 +15,13 @@ */ -/** - * Derived from gl_renderbuffer class - */ -struct texture_renderbuffer -{ - struct gl_renderbuffer Base; /**< Base class object */ - struct gl_texture_image *TexImage; - StoreTexelFunc Store; - FetchTexelFuncF Fetchf; - GLint Yoffset; /**< Layer for 1D array textures. */ - GLint Zoffset; /**< Layer for 2D array textures, or slice - * for 3D textures - */ -}; - - -/** - * Get row of values from the renderbuffer that wraps a texture image. - */ -static void -texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, void *values) -{ - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; - const GLint z = trb->Zoffset; - GLuint i; - - 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++) { - GLfloat rgba[4]; - trb->Fetchf(trb->TexImage, x + i, y, z, rgba); - UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba); - } - } - else if (rb->DataType == GL_UNSIGNED_SHORT) { - GLushort *zValues = (GLushort *) values; - for (i = 0; i < count; i++) { - GLfloat flt; - trb->Fetchf(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->Fetchf(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++) { - GLfloat flt; - trb->Fetchf(trb->TexImage, x + i, y, z, &flt); - zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; - } - } - else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) { - GLuint *zValues = (GLuint *) values; - for (i = 0; i < count; i++) { - GLfloat flt; - trb->Fetchf(trb->TexImage, x + i, y, z, &flt); - zValues[i] = (GLuint) (flt * 0xffffff); - } - } - else { - _mesa_problem(ctx, "invalid rb->DataType in texture_get_row"); - } -} - - -static void -texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; - const GLint z = trb->Zoffset; - GLuint i; - - if (rb->DataType == CHAN_TYPE) { - GLchan *rgbaOut = (GLchan *) values; - for (i = 0; i < count; i++) { - GLfloat rgba[4]; - trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset, - z, rgba); - UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba); - } - } - else if (rb->DataType == GL_UNSIGNED_SHORT) { - GLushort *zValues = (GLushort *) values; - for (i = 0; i < count; i++) { - GLfloat flt; - trb->Fetchf(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->Fetchf(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->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset, - z, &flt); - zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; - } - } - else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) { - GLuint *zValues = (GLuint *) values; - for (i = 0; i < count; i++) { - GLfloat flt; - trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset, - z, &flt); - zValues[i] = (GLuint) (flt * 0xffffff); - } - } - 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(struct gl_context *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 *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_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); - } - } - } - else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) { - const GLuint *zValues = (const GLuint *) values; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (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(struct gl_context *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); - } - } - } - else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) { - const GLuint *zValues = (const GLuint *) values; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff)); - trb->Store(trb->TexImage, x + i, y, z, &flt); - } - } - } - else { - _mesa_problem(ctx, "invalid rb->DataType in texture_put_row"); - } -} - - static void -texture_put_mono_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, 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 *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_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 = (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); - } - } - } - else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) { - const GLuint zValue = *((const GLuint *) value); - const GLfloat flt = (GLfloat) ((zValue & 0xffffff) * (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(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const 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; - - 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] + 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 = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff)); - trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt); - } - } - } - else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) { - const GLuint *zValues = (const GLuint *) values; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLfloat flt = (GLfloat) ((zValues[i] & 0xffffff) * (1.0 / 0xffffff)); - trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt); - } - } - } - else { - _mesa_problem(ctx, "invalid rb->DataType in texture_put_values"); - } -} - - -static void -texture_put_mono_values(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; - const GLint z = trb->Zoffset; - GLuint i; - - 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] + 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 = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff)); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt); - } - } - } - else if (rb->DataType == GL_UNSIGNED_INT_8_24_REV_MESA) { - const GLuint zValue = *((const GLuint *) value); - const GLfloat flt = (GLfloat) ((zValue & 0xffffff) * (1.0 / 0xffffff)); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt); - } - } - } - else { - _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_values"); - } -} - - -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) +delete_texture_wrapper(struct gl_context *ctx, struct gl_renderbuffer *rb) { ASSERT(rb->RefCount == 0); free(rb); } - -/** - * 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(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) -{ - struct texture_renderbuffer *trb; - const GLuint name = 0; - - ASSERT(att->Type == GL_TEXTURE); - ASSERT(att->Renderbuffer == NULL); - - trb = CALLOC_STRUCT(texture_renderbuffer); - if (!trb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture"); - 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.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 */ - _mesa_reference_renderbuffer(&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, @@ -528,84 +30,30 @@ wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) static void update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) { - struct texture_renderbuffer *trb - = (struct texture_renderbuffer *) att->Renderbuffer; + struct gl_renderbuffer *rb = att->Renderbuffer; + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + struct swrast_texture_image *swImage; + mesa_format format; + GLuint zOffset; (void) ctx; - ASSERT(trb); - trb->TexImage = _mesa_get_attachment_teximage(att); - ASSERT(trb->TexImage); - - 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; - } + swImage = swrast_texture_image(rb->TexImage); + assert(swImage); - trb->Fetchf = trb->TexImage->FetchTexelf; + format = swImage->Base.TexFormat; if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) { - trb->Yoffset = att->Zoffset; - trb->Zoffset = 0; + zOffset = 0; } else { - trb->Yoffset = 0; - trb->Zoffset = att->Zoffset; + zOffset = att->Zoffset; } - trb->Base.Width = trb->TexImage->Width; - trb->Base.Height = trb->TexImage->Height; - trb->Base.InternalFormat = trb->TexImage->InternalFormat; - trb->Base.Format = trb->TexImage->TexFormat; + /* Want to store linear values, not sRGB */ + rb->Format = _mesa_get_srgb_format_linear(format); - /* XXX may need more special cases here */ - switch (trb->TexImage->TexFormat) { - case MESA_FORMAT_Z24_S8: - trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; - trb->Base._BaseFormat = GL_DEPTH_STENCIL; - break; - case MESA_FORMAT_S8_Z24: - trb->Base.DataType = GL_UNSIGNED_INT_8_24_REV_MESA; - trb->Base._BaseFormat = GL_DEPTH_STENCIL; - break; - case MESA_FORMAT_Z24_X8: - trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; - trb->Base._BaseFormat = GL_DEPTH_COMPONENT; - break; - case MESA_FORMAT_X8_Z24: - trb->Base.DataType = GL_UNSIGNED_INT_8_24_REV_MESA; - trb->Base._BaseFormat = GL_DEPTH_COMPONENT; - break; - case MESA_FORMAT_Z16: - trb->Base.DataType = GL_UNSIGNED_SHORT; - trb->Base._BaseFormat = GL_DEPTH_COMPONENT; - break; - case MESA_FORMAT_Z32: - trb->Base.DataType = GL_UNSIGNED_INT; - trb->Base._BaseFormat = GL_DEPTH_COMPONENT; - break; - /* SRGB formats pre EXT_framebuffer_sRGB don't do sRGB translations on FBO readback */ - case MESA_FORMAT_SRGB8: - trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGB888, _mesa_get_texture_dimensions(att->Texture->Target)); - trb->Base.DataType = CHAN_TYPE; - trb->Base._BaseFormat = GL_RGBA; - break; - case MESA_FORMAT_SRGBA8: - trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGBA8888, _mesa_get_texture_dimensions(att->Texture->Target)); - trb->Base.DataType = CHAN_TYPE; - trb->Base._BaseFormat = GL_RGBA; - break; - case MESA_FORMAT_SARGB8: - trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_ARGB8888, _mesa_get_texture_dimensions(att->Texture->Target)); - trb->Base.DataType = CHAN_TYPE; - trb->Base._BaseFormat = GL_RGBA; - break; - default: - trb->Base.DataType = CHAN_TYPE; - trb->Base._BaseFormat = GL_RGBA; - } - trb->Base.Data = trb->TexImage->Data; + srb->Buffer = swImage->ImageSlices[zOffset]; } @@ -632,23 +80,24 @@ _swrast_render_texture(struct gl_context *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { + struct gl_renderbuffer *rb = att->Renderbuffer; (void) fb; - if (!att->Renderbuffer) { - wrap_texture(ctx, att); - } + /* plug in our texture_renderbuffer-specific functions */ + rb->Delete = delete_texture_wrapper; + update_wrapper(ctx, att); } void _swrast_finish_render_texture(struct gl_context *ctx, - struct gl_renderbuffer_attachment *att) + struct gl_renderbuffer *rb) { /* do nothing */ /* The renderbuffer texture wrapper will get deleted by the * normal mechanism for deleting renderbuffers. */ (void) ctx; - (void) att; + (void) rb; }