aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/dd.h2
-rw-r--r--mesalib/src/mesa/main/format_pack.c75
-rw-r--r--mesalib/src/mesa/main/format_pack.h3
-rw-r--r--mesalib/src/mesa/main/formats.c16
-rw-r--r--mesalib/src/mesa/main/formats.h3
-rw-r--r--mesalib/src/mesa/main/mtypes.h21
-rw-r--r--mesalib/src/mesa/main/renderbuffer.c3
-rw-r--r--mesalib/src/mesa/main/shaderapi.c5
-rw-r--r--mesalib/src/mesa/main/texgetimage.c334
-rw-r--r--mesalib/src/mesa/main/texstore.c463
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c4
11 files changed, 440 insertions, 489 deletions
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index 01cfff8ab..5816faa78 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -491,6 +491,8 @@ struct dd_function_table {
void (*FreeTextureImageBuffer)( struct gl_context *ctx, struct gl_texture_image *tImage );
/** Map a slice of a texture image into user space.
+ * Note: for GL_TEXTURE_1D_ARRAY, height must be 1, y must be 0 and slice
+ * indicates the 1D array index.
* \param texImage the texture image
* \param slice the 3D image slice or array texture slice
* \param x, y, w, h region of interest
diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c
index 390b494c0..840559bac 100644
--- a/mesalib/src/mesa/main/format_pack.c
+++ b/mesalib/src/mesa/main/format_pack.c
@@ -2494,3 +2494,78 @@ _mesa_pack_uint_24_8_depth_stencil_row(gl_format format, GLuint n,
return;
}
}
+
+
+
+/**
+ * Convert a boolean color mask to a packed color where each channel of
+ * the packed value at dst will be 0 or ~0 depending on the colorMask.
+ */
+void
+_mesa_pack_colormask(gl_format format, const GLubyte colorMask[4], void *dst)
+{
+ GLfloat maskColor[4];
+
+ switch (_mesa_get_format_datatype(format)) {
+ case GL_UNSIGNED_NORMALIZED:
+ /* simple: 1.0 will convert to ~0 in the right bit positions */
+ maskColor[0] = colorMask[0] ? 1.0 : 0.0;
+ maskColor[1] = colorMask[1] ? 1.0 : 0.0;
+ maskColor[2] = colorMask[2] ? 1.0 : 0.0;
+ maskColor[3] = colorMask[3] ? 1.0 : 0.0;
+ _mesa_pack_float_rgba_row(format, 1,
+ (const GLfloat (*)[4]) maskColor, dst);
+ break;
+ case GL_SIGNED_NORMALIZED:
+ case GL_FLOAT:
+ /* These formats are harder because it's hard to know the floating
+ * point values that will convert to ~0 for each color channel's bits.
+ * This solution just generates a non-zero value for each color channel
+ * then fixes up the non-zero values to be ~0.
+ * Note: we'll need to add special case code if we ever have to deal
+ * with formats with unequal color channel sizes, like R11_G11_B10.
+ * We issue a warning below for channel sizes other than 8,16,32.
+ */
+ {
+ GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */
+ GLuint bytes = _mesa_get_format_bytes(format);
+ GLuint i;
+
+ /* this should put non-zero values into the channels of dst */
+ maskColor[0] = colorMask[0] ? -1.0 : 0.0;
+ maskColor[1] = colorMask[1] ? -1.0 : 0.0;
+ maskColor[2] = colorMask[2] ? -1.0 : 0.0;
+ maskColor[3] = colorMask[3] ? -1.0 : 0.0;
+ _mesa_pack_float_rgba_row(format, 1,
+ (const GLfloat (*)[4]) maskColor, dst);
+
+ /* fix-up the dst channels by converting non-zero values to ~0 */
+ if (bits == 8) {
+ GLubyte *d = (GLubyte *) dst;
+ for (i = 0; i < bytes; i++) {
+ d[i] = d[i] ? 0xffff : 0x0;
+ }
+ }
+ else if (bits == 16) {
+ GLushort *d = (GLushort *) dst;
+ for (i = 0; i < bytes / 2; i++) {
+ d[i] = d[i] ? 0xffff : 0x0;
+ }
+ }
+ else if (bits == 32) {
+ GLuint *d = (GLuint *) dst;
+ for (i = 0; i < bytes / 4; i++) {
+ d[i] = d[i] ? 0xffffffffU : 0x0;
+ }
+ }
+ else {
+ _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()");
+ return;
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "unexpected format data type in gen_color_mask()");
+ return;
+ }
+}
diff --git a/mesalib/src/mesa/main/format_pack.h b/mesalib/src/mesa/main/format_pack.h
index 7df135632..f1b480510 100644
--- a/mesalib/src/mesa/main/format_pack.h
+++ b/mesalib/src/mesa/main/format_pack.h
@@ -95,4 +95,7 @@ _mesa_pack_uint_24_8_depth_stencil_row(gl_format format, GLuint n,
const GLuint *src, void *dst);
+extern void
+_mesa_pack_colormask(gl_format format, const GLubyte colorMask[4], void *dst);
+
#endif
diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c
index 1f83a5368..cca0014b1 100644
--- a/mesalib/src/mesa/main/formats.c
+++ b/mesalib/src/mesa/main/formats.c
@@ -27,6 +27,7 @@
#include "imports.h"
#include "formats.h"
#include "mfeatures.h"
+#include "macros.h"
/**
@@ -1613,6 +1614,21 @@ _mesa_get_format_bits(gl_format format, GLenum pname)
}
+GLuint
+_mesa_get_format_max_bits(gl_format format)
+{
+ const struct gl_format_info *info = _mesa_get_format_info(format);
+ GLuint max = MAX2(info->RedBits, info->GreenBits);
+ max = MAX2(max, info->BlueBits);
+ max = MAX2(max, info->AlphaBits);
+ max = MAX2(max, info->LuminanceBits);
+ max = MAX2(max, info->IntensityBits);
+ max = MAX2(max, info->DepthBits);
+ max = MAX2(max, info->StencilBits);
+ return max;
+}
+
+
/**
* Return the data type (or more specifically, the data representation)
* for the given format.
diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h
index e6b429d5f..960934338 100644
--- a/mesalib/src/mesa/main/formats.h
+++ b/mesalib/src/mesa/main/formats.h
@@ -290,6 +290,9 @@ _mesa_get_format_bytes(gl_format format);
extern GLint
_mesa_get_format_bits(gl_format format, GLenum pname);
+extern GLuint
+_mesa_get_format_max_bits(gl_format format);
+
extern GLenum
_mesa_get_format_datatype(gl_format format);
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 3d3b006d5..02452aa68 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -2538,33 +2538,12 @@ struct gl_renderbuffer
void (*PutRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask);
- /* Put/Write a row of RGB values. This is a special-case routine that's
- * only used for RGBA renderbuffers when the source data is GL_RGB. That's
- * a common case for glDrawPixels and some triangle routines.
- * The values will be of format GL_RGB and type DataType.
- */
- void (*PutRowRGB)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *values, const GLubyte *mask);
-
-
- /* Put/Write a row of identical values.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutMonoRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
- GLint x, GLint y, const void *value, const GLubyte *mask);
-
/* Put/Write values at arbitrary locations.
* The values will be of format _BaseFormat and type DataType.
*/
void (*PutValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
const GLint x[], const GLint y[], const void *values,
const GLubyte *mask);
- /* Put/Write identical values at arbitrary locations.
- * The values will be of format _BaseFormat and type DataType.
- */
- void (*PutMonoValues)(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *value, const GLubyte *mask);
};
diff --git a/mesalib/src/mesa/main/renderbuffer.c b/mesalib/src/mesa/main/renderbuffer.c
index d82b19ad5..bb8f46d11 100644
--- a/mesalib/src/mesa/main/renderbuffer.c
+++ b/mesalib/src/mesa/main/renderbuffer.c
@@ -78,10 +78,7 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
rb->GetRow = NULL;
rb->GetValues = NULL;
rb->PutRow = NULL;
- rb->PutRowRGB = NULL;
- rb->PutMonoRow = NULL;
rb->PutValues = NULL;
- rb->PutMonoValues = NULL;
}
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index c4d01abc7..b71b44b70 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -1436,7 +1436,7 @@ _mesa_UseProgramObjectARB(GLhandleARB program)
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (obj->Active) {
+ if (obj->Active && !obj->Paused) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glUseProgram(transform feedback active)");
return;
@@ -1638,7 +1638,8 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
return;
}
- if (ctx->TransformFeedback.CurrentObject->Active) {
+ if (ctx->TransformFeedback.CurrentObject->Active &&
+ !ctx->TransformFeedback.CurrentObject->Paused) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glUseShaderProgramEXT(transform feedback is active)");
return;
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index 3f2418729..738c18112 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -216,183 +216,213 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
/**
- * glGetTexImage for color formats (RGBA, RGB, alpha, LA, etc).
- * Compressed textures are handled here as well.
+ * Get a color texture image with decompression.
*/
static void
-get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_image *texImage)
+get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage,
+ GLbitfield transferOps)
{
/* don't want to apply sRGB -> RGB conversion here so override the format */
- const gl_format texFormat = _mesa_get_srgb_format_linear(texImage->TexFormat);
+ const gl_format texFormat =
+ _mesa_get_srgb_format_linear(texImage->TexFormat);
+ const GLenum baseFormat = _mesa_get_format_base_format(texFormat);
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
const GLuint depth = texImage->Depth;
- const GLenum dataType = _mesa_get_format_datatype(texFormat);
- const GLenum baseFormat = _mesa_get_format_base_format(texFormat);
- /* Normally, no pixel transfer ops are performed during glGetTexImage.
- * The only possible exception is component clamping to [0,1].
- */
- GLbitfield transferOps = 0x0;
-
- /* In general, clamping does not apply to glGetTexImage, except when
- * the returned type of the image can't hold negative values.
- */
- if (type_needs_clamping(type)) {
- /* the returned image type can't have negative values */
- if (dataType == GL_FLOAT ||
- dataType == GL_SIGNED_NORMALIZED ||
- format == GL_LUMINANCE ||
- format == GL_LUMINANCE_ALPHA) {
- transferOps |= IMAGE_CLAMP_BIT;
- }
+ GLfloat *tempImage, *srcRow;
+ GLuint row;
+
+ /* Decompress into temp float buffer, then pack into user buffer */
+ tempImage = (GLfloat *) malloc(width * height * depth
+ * 4 * sizeof(GLfloat));
+ if (!tempImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
+ return;
}
- if (_mesa_is_format_compressed(texFormat)) {
- /* Decompress into temp buffer, then pack into user buffer */
- GLfloat *tempImage, *srcRow;
- GLuint row;
+ /* Decompress the texture image - results in 'tempImage' */
+ {
+ GLubyte *srcMap;
+ GLint srcRowStride;
+ GLuint bytes, bw, bh;
- tempImage = (GLfloat *) malloc(texImage->Width * texImage->Height *
- texImage->Depth * 4 * sizeof(GLfloat));
- if (!tempImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
- return;
- }
+ bytes = _mesa_get_format_bytes(texFormat);
+ _mesa_get_format_block_size(texFormat, &bw, &bh);
- /* Decompress the texture image - results in 'tempImage' */
- {
- GLubyte *srcMap;
- GLint srcRowStride;
- GLuint bytes, bw, bh;
+ ctx->Driver.MapTextureImage(ctx, texImage, 0,
+ 0, 0, width, height,
+ GL_MAP_READ_BIT,
+ &srcMap, &srcRowStride);
+ if (srcMap) {
+ /* XXX This line is a bit of a hack to work around the
+ * mismatch of compressed row strides as returned by
+ * MapTextureImage() vs. what the texture decompression code
+ * uses. This will be fixed in the future.
+ */
+ srcRowStride = srcRowStride * bh / bytes;
- bytes = _mesa_get_format_bytes(texImage->TexFormat);
- _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
+ _mesa_decompress_image(texFormat, width, height,
+ srcMap, srcRowStride, tempImage);
- ctx->Driver.MapTextureImage(ctx, texImage, 0,
- 0, 0, width, height,
- GL_MAP_READ_BIT,
- &srcMap, &srcRowStride);
+ ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+ }
+ }
- if (srcMap) {
- /* XXX This line is a bit of a hack to work around the
- * mismatch of compressed row strides as returned by
- * MapTextureImage() vs. what the texture decompression code
- * uses. This will be fixed in the future.
- */
- srcRowStride = srcRowStride * bh / bytes;
+ if (baseFormat == GL_LUMINANCE ||
+ baseFormat == GL_LUMINANCE_ALPHA) {
+ /* Set green and blue to zero since the pack function here will
+ * compute L=R+G+B.
+ */
+ GLuint i;
+ for (i = 0; i < width * height; i++) {
+ tempImage[i * 4 + GCOMP] = tempImage[i * 4 + BCOMP] = 0.0f;
+ }
+ }
- _mesa_decompress_image(texFormat, width, height,
- srcMap, srcRowStride, tempImage);
+ srcRow = tempImage;
+ for (row = 0; row < height; row++) {
+ void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
+ width, height, format, type,
+ 0, row, 0);
- ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
- }
- else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- }
- }
+ _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow,
+ format, type, dest, &ctx->Pack, transferOps);
+ srcRow += width * 4;
+ }
- if (baseFormat == GL_LUMINANCE ||
- baseFormat == GL_LUMINANCE_ALPHA) {
- /* Set green and blue to zero since the pack function here will
- * compute L=R+G+B.
- */
- GLuint i;
- for (i = 0; i < width * height; i++) {
- tempImage[i * 4 + GCOMP] = tempImage[i * 4 + BCOMP] = 0.0f;
- }
- }
+ free(tempImage);
+}
- srcRow = tempImage;
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- 0, row, 0);
- _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow,
- format, type, dest, &ctx->Pack, transferOps);
- srcRow += width * 4;
- }
+/**
+ * Get an uncompressed color texture image.
+ */
+static void
+get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage,
+ GLbitfield transferOps)
+{
+ /* don't want to apply sRGB -> RGB conversion here so override the format */
+ const gl_format texFormat =
+ _mesa_get_srgb_format_linear(texImage->TexFormat);
+ const GLuint width = texImage->Width;
+ const GLuint height = texImage->Height;
+ const GLuint depth = texImage->Depth;
+ GLuint img, row;
+ GLfloat (*rgba)[4];
- free(tempImage);
+ /* Allocate buffer for one row of texels */
+ rgba = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+ if (!rgba) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
+ return;
}
- else {
- /* No decompression needed */
- GLuint img, row;
- GLfloat (*rgba)[4];
- rgba = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
- if (!rgba) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
- return;
- }
+ for (img = 0; img < depth; img++) {
+ GLubyte *srcMap;
+ GLint rowstride;
- for (img = 0; img < depth; img++) {
- GLubyte *srcMap;
- GLint rowstride;
-
- /* map src texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, img,
- 0, 0, width, height, GL_MAP_READ_BIT,
- &srcMap, &rowstride);
-
- if (srcMap) {
- for (row = 0; row < height; row++) {
- const GLubyte *src = srcMap + row * rowstride;
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
-
- _mesa_unpack_rgba_row(texFormat, width, src, rgba);
-
- if (texImage->_BaseFormat == GL_ALPHA) {
- GLint col;
- for (col = 0; col < width; col++) {
- rgba[col][RCOMP] = 0.0F;
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- }
+ /* map src texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, img,
+ 0, 0, width, height, GL_MAP_READ_BIT,
+ &srcMap, &rowstride);
+ if (srcMap) {
+ for (row = 0; row < height; row++) {
+ const GLubyte *src = srcMap + row * rowstride;
+ void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
+ width, height, format, type,
+ img, row, 0);
+
+ _mesa_unpack_rgba_row(texFormat, width, src, rgba);
+
+ if (texImage->_BaseFormat == GL_ALPHA) {
+ GLint col;
+ for (col = 0; col < width; col++) {
+ rgba[col][RCOMP] = 0.0F;
+ rgba[col][GCOMP] = 0.0F;
+ rgba[col][BCOMP] = 0.0F;
}
- else if (texImage->_BaseFormat == GL_LUMINANCE) {
- GLint col;
- for (col = 0; col < width; col++) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- rgba[col][ACOMP] = 1.0F;
- }
+ }
+ else if (texImage->_BaseFormat == GL_LUMINANCE) {
+ GLint col;
+ for (col = 0; col < width; col++) {
+ rgba[col][GCOMP] = 0.0F;
+ rgba[col][BCOMP] = 0.0F;
+ rgba[col][ACOMP] = 1.0F;
}
- else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
- GLint col;
- for (col = 0; col < width; col++) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- }
+ }
+ else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
+ GLint col;
+ for (col = 0; col < width; col++) {
+ rgba[col][GCOMP] = 0.0F;
+ rgba[col][BCOMP] = 0.0F;
}
- else if (texImage->_BaseFormat == GL_INTENSITY) {
- GLint col;
- for (col = 0; col < width; col++) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- rgba[col][ACOMP] = 1.0F;
- }
+ }
+ else if (texImage->_BaseFormat == GL_INTENSITY) {
+ GLint col;
+ for (col = 0; col < width; col++) {
+ rgba[col][GCOMP] = 0.0F;
+ rgba[col][BCOMP] = 0.0F;
+ rgba[col][ACOMP] = 1.0F;
}
-
- _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
- format, type, dest,
- &ctx->Pack, transferOps);
}
- /* Unmap the src texture buffer */
- ctx->Driver.UnmapTextureImage(ctx, texImage, img);
- }
- else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- break;
+ _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
+ format, type, dest,
+ &ctx->Pack, transferOps);
}
+
+ /* Unmap the src texture buffer */
+ ctx->Driver.UnmapTextureImage(ctx, texImage, img);
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+ break;
}
+ }
+
+ free(rgba);
+}
+
- free(rgba);
+/**
+ * glGetTexImage for color formats (RGBA, RGB, alpha, LA, etc).
+ * Compressed textures are handled here as well.
+ */
+static void
+get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage)
+{
+ const GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
+ GLbitfield transferOps = 0x0;
+
+ /* In general, clamping does not apply to glGetTexImage, except when
+ * the returned type of the image can't hold negative values.
+ */
+ if (type_needs_clamping(type)) {
+ /* the returned image type can't have negative values */
+ if (dataType == GL_FLOAT ||
+ dataType == GL_SIGNED_NORMALIZED ||
+ format == GL_LUMINANCE ||
+ format == GL_LUMINANCE_ALPHA) {
+ transferOps |= IMAGE_CLAMP_BIT;
+ }
+ }
+
+ if (_mesa_is_format_compressed(texImage->TexFormat)) {
+ get_tex_rgba_compressed(ctx, dimensions, format, type,
+ pixels, texImage, transferOps);
+ }
+ else {
+ get_tex_rgba_uncompressed(ctx, dimensions, format, type,
+ pixels, texImage, transferOps);
}
}
@@ -702,20 +732,20 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
return GL_TRUE;
}
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- /* out of memory */
- return GL_TRUE;
- }
-
if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
- /*GL_INVALID_OPERATION is generated by a format/type
+ /* GL_INVALID_OPERATION is generated by a format/type
* mismatch (see the 1.2 spec page 94, sec 3.6.4.)
*/
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(target)");
return GL_TRUE;
}
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (!texImage) {
+ /* non-existant texture image */
+ return GL_TRUE;
+ }
+
baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
/* Make sure the requested image format is compatible with the
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index a57a38e12..86c35d38f 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -4565,9 +4565,137 @@ get_read_write_mode(GLenum userFormat, gl_format texFormat)
return GL_MAP_WRITE_BIT;
}
+
+/**
+ * Helper function for storing 1D, 2D, 3D whole and subimages into texture
+ * memory.
+ * The source of the image data may be user memory or a PBO. In the later
+ * case, we'll map the PBO, copy from it, then unmap it.
+ */
+static void
+store_texsubimage(struct gl_context *ctx,
+ struct gl_texture_image *texImage,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ const char *caller)
+
+{
+ const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
+ const GLenum target = texImage->TexObject->Target;
+ GLboolean success = GL_FALSE;
+ GLuint dims, slice, numSlices = 1, sliceOffset = 0;
+ GLint srcImageStride = 0;
+ const GLubyte *src;
+
+ assert(xoffset + width <= texImage->Width);
+ assert(yoffset + height <= texImage->Height);
+ assert(zoffset + depth <= texImage->Depth);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ dims = 1;
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_3D:
+ dims = 3;
+ break;
+ default:
+ dims = 2;
+ }
+
+ /* get pointer to src pixels (may be in a pbo which we'll map here) */
+ src = (const GLubyte *)
+ _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
+ format, type, pixels, packing, caller);
+ if (!src)
+ return;
+
+ /* compute slice info (and do some sanity checks) */
+ switch (target) {
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_CUBE_MAP:
+ /* one image slice, nothing special needs to be done */
+ break;
+ case GL_TEXTURE_1D:
+ assert(height == 1);
+ assert(depth == 1);
+ assert(yoffset == 0);
+ assert(zoffset == 0);
+ break;
+ case GL_TEXTURE_1D_ARRAY:
+ assert(depth == 1);
+ assert(zoffset == 0);
+ numSlices = height;
+ sliceOffset = yoffset;
+ height = 1;
+ yoffset = 0;
+ srcImageStride = _mesa_image_row_stride(packing, width, format, type);
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ numSlices = depth;
+ sliceOffset = zoffset;
+ depth = 1;
+ zoffset = 0;
+ srcImageStride = _mesa_image_image_stride(packing, width, height,
+ format, type);
+ break;
+ case GL_TEXTURE_3D:
+ /* we'll store 3D images as a series of slices */
+ numSlices = depth;
+ sliceOffset = zoffset;
+ srcImageStride = _mesa_image_image_stride(packing, width, height,
+ format, type);
+ break;
+ default:
+ _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
+ return;
+ }
+
+ assert(numSlices == 1 || srcImageStride != 0);
+
+ for (slice = 0; slice < numSlices; slice++) {
+ GLubyte *dstMap;
+ GLint dstRowStride;
+
+ ctx->Driver.MapTextureImage(ctx, texImage,
+ slice + sliceOffset,
+ xoffset, yoffset, width, height,
+ mapMode, &dstMap, &dstRowStride);
+ if (dstMap) {
+ /* Note: we're only storing a 2D (or 1D) slice at a time but we need
+ * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
+ * used for 3D images.
+ */
+ success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ &dstMap,
+ width, height, 1, /* w, h, d */
+ format, type, src, packing);
+
+ ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
+ }
+
+ src += srcImageStride;
+
+ if (!success)
+ break;
+ }
+
+ if (!success)
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+}
+
+
+
/**
- * This is the software fallback for Driver.TexImage1D().
- * \sa _mesa_store_teximage2d()
+ * This is the fallback for Driver.TexImage1D().
*/
void
_mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4578,13 +4706,6 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
- GLubyte *dstMap;
- GLint dstRowStride;
- GLboolean success;
-
- (void) border;
-
if (width == 0)
return;
@@ -4595,47 +4716,14 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
return;
}
- pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
- pixels, packing, "glTexImage1D");
- if (!pixels) {
- /* Note: we check for a NULL image pointer here, _after_ we allocated
- * memory for the texture. That's what the GL spec calls for.
- */
- return;
- }
-
- /* Map dest texture buffer (write to whole region) */
- ctx->Driver.MapTextureImage(ctx, texImage, 0,
- 0, 0, width, 1,
- rwMode,
- &dstMap, &dstRowStride);
- if (dstMap) {
- success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
- texImage->TexFormat,
- 0, 0, 0, /* dstX/Y/Zoffset */
- 0, /* dstRowStride */
- &dstMap,
- width, 1, 1,
- format, type, pixels, packing);
-
- ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
- }
- else {
- success = GL_FALSE;
- }
-
- if (!success)
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
-
- _mesa_unmap_teximage_pbo(ctx, packing);
+ store_texsubimage(ctx, texImage,
+ 0, 0, 0, width, 1, 1,
+ format, type, pixels, packing, "glTexImage1D");
}
/**
- * This is the software fallback for Driver.TexImage2D().
- *
- * This function is oriented toward storing images in main memory, rather
- * than VRAM. Device driver's can easily plug in their own replacement.
+ * This is the fallback for Driver.TexImage2D().
*/
void
_mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4646,13 +4734,6 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
- GLubyte *dstMap;
- GLint dstRowStride;
- GLboolean success;
-
- (void) border;
-
if (width == 0 || height == 0)
return;
@@ -4663,80 +4744,15 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
return;
}
- pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
- pixels, packing, "glTexImage2D");
- if (!pixels) {
- /* Note: we check for a NULL image pointer here, _after_ we allocated
- * memory for the texture. That's what the GL spec calls for.
- */
- return;
- }
-
- if (target == GL_TEXTURE_1D_ARRAY) {
- const GLint srcStride =
- _mesa_image_row_stride(packing, width, format, type);
- int y;
-
- success = GL_TRUE;
-
- for (y = 0; y < height; y++) {
- /* Map dest texture buffer (write to whole region) */
- ctx->Driver.MapTextureImage(ctx, texImage, y,
- 0, 0, width, 1,
- rwMode,
- &dstMap, &dstRowStride);
- if (dstMap) {
- success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
- texImage->TexFormat,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- &dstMap,
- width, 1, 1,
- format, type, pixels, packing);
- ctx->Driver.UnmapTextureImage(ctx, texImage, y);
- }
- else {
- success = GL_FALSE;
- }
-
- if (!success)
- break;
-
- pixels = (const GLubyte *) pixels + srcStride;
- }
- } else {
- /* Map dest texture buffer (write to whole region) */
- ctx->Driver.MapTextureImage(ctx, texImage, 0,
- 0, 0, width, height,
- rwMode,
- &dstMap, &dstRowStride);
- if (dstMap) {
- success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
- texImage->TexFormat,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- &dstMap,
- width, height, 1,
- format, type, pixels, packing);
-
- ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
- }
- else {
- success = GL_FALSE;
- }
- }
-
- if (!success)
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
-
- _mesa_unmap_teximage_pbo(ctx, packing);
+ store_texsubimage(ctx, texImage,
+ 0, 0, 0, width, height, 1,
+ format, type, pixels, packing, "glTexImage2D");
}
/**
- * This is the software fallback for Driver.TexImage3D().
- * \sa _mesa_store_teximage2d()
+ * This is the fallback for Driver.TexImage3D().
*/
void
_mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4747,14 +4763,6 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
- GLboolean success = GL_TRUE;
- GLint slice;
- GLubyte **sliceMaps;
- GLint dstRowStride;
-
- (void) border;
-
if (width == 0 || height == 0 || depth == 0)
return;
@@ -4765,66 +4773,16 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
return;
}
- pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth,
- format, type,
- pixels, packing, "glTexImage3D");
- if (!pixels) {
- /* Note: we check for a NULL image pointer here, _after_ we allocated
- * memory for the texture. That's what the GL spec calls for.
- */
- return;
- }
-
- if (target == GL_TEXTURE_1D_ARRAY) {
- depth = height;
- height = 1;
- }
-
- sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
-
- /* Map dest texture buffer slices */
- for (slice = 0; slice < depth; slice++) {
- ctx->Driver.MapTextureImage(ctx, texImage, slice,
- 0, 0, width, height,
- rwMode,
- &sliceMaps[slice], &dstRowStride);
- if (!sliceMaps[slice]) {
- success = GL_FALSE;
- break;
- }
- }
-
- if (success) {
- success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
- texImage->TexFormat,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- sliceMaps,
- width, height, depth,
- format, type, pixels, packing);
- }
-
- /* Unmap dest texture buffer slices */
- for (slice = 0; slice < depth; slice++) {
- if (sliceMaps[slice]) {
- ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
- }
- }
-
- if (!success)
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
-
- _mesa_unmap_teximage_pbo(ctx, packing);
-
- free(sliceMaps);
+ store_texsubimage(ctx, texImage,
+ 0, 0, 0, width, height, depth,
+ format, type, pixels, packing, "glTexImage3D");
}
/*
- * This is the software fallback for Driver.TexSubImage1D()
- * and Driver.CopyTexSubImage1D().
+ * This is the fallback for Driver.TexSubImage1D().
*/
void
_mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4834,49 +4792,15 @@ _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
- GLubyte *dstMap;
- GLint dstRowStride;
- GLboolean success;
-
- /* get pointer to src pixels (may be in a pbo which we'll map here) */
- pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
- pixels, packing, "glTexSubImage1D");
- if (!pixels)
- return;
-
- /* Map dest texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, 0,
- xoffset, 0, width, 1,
- rwMode,
- &dstMap, &dstRowStride);
-
- if (dstMap) {
- success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
- texImage->TexFormat,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- &dstMap,
- width, 1, 1,
- format, type, pixels, packing);
-
- ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
- }
- else {
- success = GL_FALSE;
- }
-
- if (!success)
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
-
- _mesa_unmap_teximage_pbo(ctx, packing);
+ store_texsubimage(ctx, texImage,
+ xoffset, 0, 0, width, 1, 1,
+ format, type, pixels, packing, "glTexSubImage1D");
}
/**
- * This is the software fallback for Driver.TexSubImage2D()
- * and Driver.CopyTexSubImage2D().
+ * This is the fallback for Driver.TexSubImage2D().
*/
void
_mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4887,48 +4811,14 @@ _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
- GLubyte *dstMap;
- GLint dstRowStride;
- GLboolean success;
-
- /* get pointer to src pixels (may be in a pbo which we'll map here) */
- pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
- pixels, packing, "glTexSubImage2D");
- if (!pixels)
- return;
-
- /* Map dest texture buffer */
- ctx->Driver.MapTextureImage(ctx, texImage, 0,
- xoffset, yoffset, width, height,
- rwMode,
- &dstMap, &dstRowStride);
-
- if (dstMap) {
- success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
- texImage->TexFormat,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- &dstMap,
- width, height, 1,
- format, type, pixels, packing);
-
- ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
- }
- else {
- success = GL_FALSE;
- }
-
- if (!success)
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
-
- _mesa_unmap_teximage_pbo(ctx, packing);
+ store_texsubimage(ctx, texImage,
+ xoffset, yoffset, 0, width, height, 1,
+ format, type, pixels, packing, "glTexSubImage2D");
}
/*
- * This is the software fallback for Driver.TexSubImage3D().
- * and Driver.CopyTexSubImage3D().
+ * This is the fallback for Driver.TexSubImage3D().
*/
void
_mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4939,56 +4829,9 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
- GLboolean success = GL_TRUE;
- GLint slice;
- GLubyte **sliceMaps;
- GLint dstRowStride;
-
- /* get pointer to src pixels (may be in a pbo which we'll map here) */
- pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
- type, pixels, packing,
- "glTexSubImage3D");
- if (!pixels)
- return;
-
- sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
-
- /* Map dest texture buffer slices */
- for (slice = 0; slice < depth; slice++) {
- ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
- xoffset, yoffset, width, height,
- rwMode,
- &sliceMaps[slice], &dstRowStride);
- if (!sliceMaps[slice]) {
- success = GL_FALSE;
- break;
- }
- }
-
- if (success) {
- success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
- texImage->TexFormat,
- 0, 0, 0,
- dstRowStride,
- sliceMaps,
- width, height, depth,
- format, type, pixels, packing);
- }
-
- /* Unmap dest texture buffer slices */
- for (slice = 0; slice < depth; slice++) {
- if (sliceMaps[slice]) {
- ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
- }
- }
-
- if (!success)
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
-
- _mesa_unmap_teximage_pbo(ctx, packing);
-
- free(sliceMaps);
+ store_texsubimage(ctx, texImage,
+ xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels, packing, "glTexSubImage3D");
}
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index 53c09e265..be0d0ff19 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -98,7 +98,8 @@ reference_transform_feedback_object(struct gl_transform_feedback_object **ptr,
GLboolean
_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode)
{
- if (ctx->TransformFeedback.CurrentObject->Active) {
+ if (ctx->TransformFeedback.CurrentObject->Active &&
+ !ctx->TransformFeedback.CurrentObject->Paused) {
switch (mode) {
case GL_POINTS:
return ctx->TransformFeedback.Mode == GL_POINTS;
@@ -387,6 +388,7 @@ _mesa_EndTransformFeedback(void)
FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK);
ctx->TransformFeedback.CurrentObject->Active = GL_FALSE;
+ ctx->TransformFeedback.CurrentObject->Paused = GL_FALSE;
ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE;
assert(ctx->Driver.EndTransformFeedback);