aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r--mesalib/src/mesa/main/accum.c24
-rw-r--r--mesalib/src/mesa/main/fbobject.c69
-rw-r--r--mesalib/src/mesa/main/format_unpack.c503
-rw-r--r--mesalib/src/mesa/main/format_unpack.h7
-rw-r--r--mesalib/src/mesa/main/formats.c2
-rw-r--r--mesalib/src/mesa/main/readpix.c2
-rw-r--r--mesalib/src/mesa/main/shaderapi.c2
-rw-r--r--mesalib/src/mesa/main/shared.c2
-rw-r--r--mesalib/src/mesa/main/texstate.c2
-rw-r--r--mesalib/src/mesa/main/version.h6
-rw-r--r--mesalib/src/mesa/program/nvvertparse.c1
-rw-r--r--mesalib/src/mesa/program/symbol_table.c977
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_clip.c24
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_rasterizer.c7
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bitmap.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawpixels.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_manager.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c2
-rw-r--r--mesalib/src/mesa/swrast/s_blit.c183
22 files changed, 1253 insertions, 570 deletions
diff --git a/mesalib/src/mesa/main/accum.c b/mesalib/src/mesa/main/accum.c
index a8c30c223..df6f219bf 100644
--- a/mesalib/src/mesa/main/accum.c
+++ b/mesalib/src/mesa/main/accum.c
@@ -117,19 +117,6 @@ _mesa_init_accum_dispatch(struct _glapi_table *disp)
}
-#endif /* FEATURE_accum */
-
-
-void
-_mesa_init_accum( struct gl_context *ctx )
-{
- /* Accumulate buffer group */
- ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
-}
-
-
-
-
/**
* Clear the accumulation buffer by mapping the renderbuffer and
* writing the clear color to it. Called by the driver's implementation
@@ -507,3 +494,14 @@ _mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value)
break;
}
}
+
+
+#endif /* FEATURE_accum */
+
+
+void
+_mesa_init_accum( struct gl_context *ctx )
+{
+ /* Accumulate buffer group */
+ ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+}
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 912170aba..aefcaf350 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -2579,6 +2579,44 @@ find_attachment(const struct gl_framebuffer *fb,
}
+/**
+ * Helper function for checking if the datatypes of color buffers are
+ * compatible for glBlitFramebuffer. From the 3.1 spec, page 198:
+ *
+ * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
+ * and any of the following conditions hold:
+ * - The read buffer contains fixed-point or floating-point values and any
+ * draw buffer contains neither fixed-point nor floating-point values.
+ * - The read buffer contains unsigned integer values and any draw buffer
+ * does not contain unsigned integer values.
+ * - The read buffer contains signed integer values and any draw buffer
+ * does not contain signed integer values."
+ */
+static GLboolean
+compatible_color_datatypes(gl_format srcFormat, gl_format dstFormat)
+{
+ GLenum srcType = _mesa_get_format_datatype(srcFormat);
+ GLenum dstType = _mesa_get_format_datatype(dstFormat);
+
+ if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
+ assert(srcType == GL_UNSIGNED_NORMALIZED ||
+ srcType == GL_SIGNED_NORMALIZED ||
+ srcType == GL_FLOAT);
+ /* Boil any of those types down to GL_FLOAT */
+ srcType = GL_FLOAT;
+ }
+
+ if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
+ assert(dstType == GL_UNSIGNED_NORMALIZED ||
+ dstType == GL_SIGNED_NORMALIZED ||
+ dstType == GL_FLOAT);
+ /* Boil any of those types down to GL_FLOAT */
+ dstType = GL_FLOAT;
+ }
+
+ return srcType == dstType;
+}
+
/**
* Blit rectangular region, optionally from one framebuffer to another.
@@ -2663,6 +2701,12 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
colorReadRb = colorDrawRb = NULL;
mask &= ~GL_COLOR_BUFFER_BIT;
}
+ else if (!compatible_color_datatypes(colorReadRb->Format,
+ colorDrawRb->Format)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(color buffer datatypes mismatch)");
+ return;
+ }
}
else {
colorReadRb = colorDrawRb = NULL;
@@ -2683,10 +2727,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if ((readRb == NULL) || (drawRb == NULL)) {
mask &= ~GL_STENCIL_BUFFER_BIT;
}
- else if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
+ else if (readRb->Format != drawRb->Format) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(stencil buffer size mismatch)");
+ "glBlitFramebufferEXT(stencil buffer format mismatch)");
return;
}
}
@@ -2706,10 +2749,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if ((readRb == NULL) || (drawRb == NULL)) {
mask &= ~GL_DEPTH_BUFFER_BIT;
}
- else if (_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) {
+ else if (readRb->Format != drawRb->Format) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(depth buffer size mismatch)");
+ "glBlitFramebufferEXT(depth buffer format mismatch)");
return;
}
}
@@ -2718,7 +2760,7 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
drawFb->Visual.samples > 0 &&
readFb->Visual.samples != drawFb->Visual.samples) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(mismatched samples");
+ "glBlitFramebufferEXT(mismatched samples)");
return;
}
@@ -2742,6 +2784,19 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
}
+ if (filter == GL_LINEAR && (mask & GL_COLOR_BUFFER_BIT)) {
+ /* 3.1 spec, page 199:
+ * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
+ * if filter is LINEAR and read buffer contains integer data."
+ */
+ GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
+ if (type == GL_INT || type == GL_UNSIGNED_INT) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(integer color type)");
+ return;
+ }
+ }
+
if (!ctx->Extensions.EXT_framebuffer_blit) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT");
return;
diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c
index a22ff5a61..ff98c69cd 100644
--- a/mesalib/src/mesa/main/format_unpack.c
+++ b/mesalib/src/mesa/main/format_unpack.c
@@ -29,6 +29,22 @@
#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
+
+/* Expand 1, 2, 3, 4, 5, 6-bit values to fill 8 bits */
+
+#define EXPAND_1_8(X) ( (X) ? 0xff : 0x0 )
+
+#define EXPAND_2_8(X) ( ((X) << 6) | ((X) << 4) | ((X) << 2) | (X) )
+
+#define EXPAND_3_8(X) ( ((X) << 5) | ((X) << 2) | ((X) >> 1) )
+
+#define EXPAND_4_8(X) ( ((X) << 4) | (X) )
+
+#define EXPAND_5_8(X) ( ((X) << 3) | ((X) >> 2) )
+
+#define EXPAND_6_8(X) ( ((X) << 2) | ((X) >> 4) )
+
+
/**
* Convert an 8-bit sRGB value from non-linear space to a
* linear RGB value in [0, 1].
@@ -57,6 +73,10 @@ nonlinear_to_linear(GLubyte cs8)
}
+/**********************************************************************/
+/* Unpack, returning GLfloat colors */
+/**********************************************************************/
+
typedef void (*unpack_rgba_func)(const void *src, GLfloat dst[][4], GLuint n);
@@ -1566,6 +1586,9 @@ get_unpack_rgba_function(gl_format format)
}
+/**
+ * Unpack rgba colors, returning as GLfloat values.
+ */
void
_mesa_unpack_rgba_row(gl_format format, GLuint n,
const void *src, GLfloat dst[][4])
@@ -1574,6 +1597,482 @@ _mesa_unpack_rgba_row(gl_format format, GLuint n,
unpack(src, dst, n);
}
+
+/**********************************************************************/
+/* Unpack, returning GLubyte colors */
+/**********************************************************************/
+
+
+static void
+unpack_ubyte_RGBA8888(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] >> 24);
+ dst[i][GCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][BCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][ACOMP] = (s[i] ) & 0xff;
+ }
+}
+
+static void
+unpack_ubyte_RGBA8888_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] ) & 0xff;
+ dst[i][GCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][BCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][ACOMP] = (s[i] >> 24);
+ }
+}
+
+static void
+unpack_ubyte_ARGB8888(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][GCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][BCOMP] = (s[i] ) & 0xff;
+ dst[i][ACOMP] = (s[i] >> 24);
+ }
+}
+
+static void
+unpack_ubyte_ARGB8888_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][GCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][BCOMP] = (s[i] >> 24);
+ dst[i][ACOMP] = (s[i] ) & 0xff;
+ }
+}
+
+static void
+unpack_ubyte_RGBX8888(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] >> 24);
+ dst[i][GCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][BCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_RGBX8888_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] ) & 0xff;
+ dst[i][GCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][BCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_XRGB8888(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][GCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][BCOMP] = (s[i] ) & 0xff;
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_XRGB8888_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = (s[i] >> 8) & 0xff;
+ dst[i][GCOMP] = (s[i] >> 16) & 0xff;
+ dst[i][BCOMP] = (s[i] >> 24);
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_RGB888(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = (const GLubyte *) src;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = s[i*3+2];
+ dst[i][GCOMP] = s[i*3+1];
+ dst[i][BCOMP] = s[i*3+0];
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_BGR888(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = (const GLubyte *) src;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = s[i*3+0];
+ dst[i][GCOMP] = s[i*3+1];
+ dst[i][BCOMP] = s[i*3+2];
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_RGB565(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f);
+ dst[i][GCOMP] = EXPAND_6_8((s[i] >> 5 ) & 0x3f);
+ dst[i][BCOMP] = EXPAND_5_8( s[i] & 0x1f);
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_RGB565_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLuint t = (s[i] >> 8) | (s[i] << 8); /* byte swap */
+ dst[i][RCOMP] = EXPAND_5_8((t >> 11) & 0x1f);
+ dst[i][GCOMP] = EXPAND_6_8((t >> 5 ) & 0x3f);
+ dst[i][BCOMP] = EXPAND_5_8( t & 0x1f);
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_ARGB4444(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf);
+ dst[i][GCOMP] = EXPAND_4_8((s[i] >> 4) & 0xf);
+ dst[i][BCOMP] = EXPAND_4_8((s[i] ) & 0xf);
+ dst[i][ACOMP] = EXPAND_4_8((s[i] >> 12) & 0xf);
+ }
+}
+
+static void
+unpack_ubyte_ARGB4444_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = EXPAND_4_8((s[i] ) & 0xf);
+ dst[i][GCOMP] = EXPAND_4_8((s[i] >> 12) & 0xf);
+ dst[i][BCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf);
+ dst[i][ACOMP] = EXPAND_4_8((s[i] >> 4) & 0xf);
+ }
+}
+
+static void
+unpack_ubyte_RGBA5551(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f);
+ dst[i][GCOMP] = EXPAND_5_8((s[i] >> 6) & 0x1f);
+ dst[i][BCOMP] = EXPAND_5_8((s[i] >> 1) & 0x1f);
+ dst[i][ACOMP] = EXPAND_1_8((s[i] ) & 0x01);
+ }
+}
+
+static void
+unpack_ubyte_ARGB1555(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = EXPAND_5_8((s[i] >> 10) & 0x1f);
+ dst[i][GCOMP] = EXPAND_5_8((s[i] >> 5) & 0x1f);
+ dst[i][BCOMP] = EXPAND_5_8((s[i] >> 0) & 0x1f);
+ dst[i][ACOMP] = EXPAND_1_8((s[i] >> 15) & 0x01);
+ }
+}
+
+static void
+unpack_ubyte_ARGB1555_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLushort tmp = (s[i] << 8) | (s[i] >> 8); /* byteswap */
+ dst[i][RCOMP] = EXPAND_5_8((tmp >> 10) & 0x1f);
+ dst[i][GCOMP] = EXPAND_5_8((tmp >> 5) & 0x1f);
+ dst[i][BCOMP] = EXPAND_5_8((tmp >> 0) & 0x1f);
+ dst[i][ACOMP] = EXPAND_1_8((tmp >> 15) & 0x01);
+ }
+}
+
+static void
+unpack_ubyte_AL44(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = ((const GLubyte *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] =
+ dst[i][GCOMP] =
+ dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xf);
+ dst[i][ACOMP] = EXPAND_4_8(s[i] >> 4);
+ }
+}
+
+static void
+unpack_ubyte_AL88(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] =
+ dst[i][GCOMP] =
+ dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xff);
+ dst[i][ACOMP] = EXPAND_4_8(s[i] >> 8);
+ }
+}
+
+static void
+unpack_ubyte_AL88_REV(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] =
+ dst[i][GCOMP] =
+ dst[i][BCOMP] = EXPAND_4_8(s[i] >> 8);
+ dst[i][ACOMP] = EXPAND_4_8(s[i] & 0xff);
+ }
+}
+
+static void
+unpack_ubyte_RGB332(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = ((const GLubyte *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = EXPAND_3_8((s[i] >> 5) & 0x7);
+ dst[i][GCOMP] = EXPAND_3_8((s[i] >> 2) & 0x7);
+ dst[i][BCOMP] = EXPAND_2_8((s[i] ) & 0x3);
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_A8(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = ((const GLubyte *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] =
+ dst[i][GCOMP] =
+ dst[i][BCOMP] = 0;
+ dst[i][ACOMP] = s[i];
+ }
+}
+
+static void
+unpack_ubyte_L8(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = ((const GLubyte *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] =
+ dst[i][GCOMP] =
+ dst[i][BCOMP] = s[i];
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+
+static void
+unpack_ubyte_I8(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = ((const GLubyte *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] =
+ dst[i][GCOMP] =
+ dst[i][BCOMP] =
+ dst[i][ACOMP] = s[i];
+ }
+}
+
+static void
+unpack_ubyte_R8(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLubyte *s = ((const GLubyte *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][0] = s[i];
+ dst[i][1] =
+ dst[i][2] = 0;
+ dst[i][3] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_GR88(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = s[i] & 0xff;
+ dst[i][GCOMP] = s[i] >> 8;
+ dst[i][BCOMP] = 0;
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+static void
+unpack_ubyte_RG88(const void *src, GLubyte dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = s[i] >> 8;
+ dst[i][GCOMP] = s[i] & 0xff;
+ dst[i][BCOMP] = 0;
+ dst[i][ACOMP] = 0xff;
+ }
+}
+
+
+/**
+ * Unpack rgba colors, returning as GLubyte values. This should usually
+ * only be used for unpacking formats that use 8 bits or less per channel.
+ */
+void
+_mesa_unpack_ubyte_rgba_row(gl_format format, GLuint n,
+ const void *src, GLubyte dst[][4])
+{
+ switch (format) {
+ case MESA_FORMAT_RGBA8888:
+ unpack_ubyte_RGBA8888(src, dst, n);
+ break;
+ case MESA_FORMAT_RGBA8888_REV:
+ unpack_ubyte_RGBA8888_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_ARGB8888:
+ unpack_ubyte_ARGB8888(src, dst, n);
+ break;
+ case MESA_FORMAT_ARGB8888_REV:
+ unpack_ubyte_ARGB8888_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_RGBX8888:
+ unpack_ubyte_RGBX8888(src, dst, n);
+ break;
+ case MESA_FORMAT_RGBX8888_REV:
+ unpack_ubyte_RGBX8888_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_XRGB8888:
+ unpack_ubyte_XRGB8888(src, dst, n);
+ break;
+ case MESA_FORMAT_XRGB8888_REV:
+ unpack_ubyte_XRGB8888_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_RGB888:
+ unpack_ubyte_RGB888(src, dst, n);
+ break;
+ case MESA_FORMAT_BGR888:
+ unpack_ubyte_BGR888(src, dst, n);
+ break;
+ case MESA_FORMAT_RGB565:
+ unpack_ubyte_RGB565(src, dst, n);
+ break;
+ case MESA_FORMAT_RGB565_REV:
+ unpack_ubyte_RGB565_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_ARGB4444:
+ unpack_ubyte_ARGB4444(src, dst, n);
+ break;
+ case MESA_FORMAT_ARGB4444_REV:
+ unpack_ubyte_ARGB4444_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_RGBA5551:
+ unpack_ubyte_RGBA5551(src, dst, n);
+ break;
+ case MESA_FORMAT_ARGB1555:
+ unpack_ubyte_ARGB1555(src, dst, n);
+ break;
+ case MESA_FORMAT_ARGB1555_REV:
+ unpack_ubyte_ARGB1555_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_AL44:
+ unpack_ubyte_AL44(src, dst, n);
+ break;
+ case MESA_FORMAT_AL88:
+ unpack_ubyte_AL88(src, dst, n);
+ break;
+ case MESA_FORMAT_AL88_REV:
+ unpack_ubyte_AL88_REV(src, dst, n);
+ break;
+ case MESA_FORMAT_RGB332:
+ unpack_ubyte_RGB332(src, dst, n);
+ break;
+ case MESA_FORMAT_A8:
+ unpack_ubyte_A8(src, dst, n);
+ break;
+ case MESA_FORMAT_L8:
+ unpack_ubyte_L8(src, dst, n);
+ break;
+ case MESA_FORMAT_I8:
+ unpack_ubyte_I8(src, dst, n);
+ break;
+ case MESA_FORMAT_R8:
+ unpack_ubyte_R8(src, dst, n);
+ break;
+ case MESA_FORMAT_GR88:
+ unpack_ubyte_GR88(src, dst, n);
+ break;
+ case MESA_FORMAT_RG88:
+ unpack_ubyte_RG88(src, dst, n);
+ break;
+ default:
+ /* get float values, convert to ubyte */
+ {
+ GLfloat *tmp = (GLfloat *) malloc(n * 4 * sizeof(GLfloat));
+ if (tmp) {
+ GLuint i;
+ _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp);
+ for (i = 0; i < n; i++) {
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[i][0], tmp[i*4+0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[i][1], tmp[i*4+1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[i][2], tmp[i*4+2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[i][3], tmp[i*4+3]);
+ }
+ free(tmp);
+ }
+ }
+ break;
+ }
+}
+
+
+/**********************************************************************/
+/* Unpack, returning GLuint colors */
+/**********************************************************************/
+
static void
unpack_int_rgba_RGBA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n)
{
@@ -1770,8 +2269,8 @@ unpack_int_rgba_ARGB2101010_UINT(const GLuint *src, GLuint dst[][4], GLuint n)
}
void
-_mesa_unpack_int_rgba_row(gl_format format, GLuint n,
- const void *src, GLuint dst[][4])
+_mesa_unpack_uint_rgba_row(gl_format format, GLuint n,
+ const void *src, GLuint dst[][4])
{
switch (format) {
/* Since there won't be any sign extension happening, there's no need to
diff --git a/mesalib/src/mesa/main/format_unpack.h b/mesalib/src/mesa/main/format_unpack.h
index c5348d30d..aad800dd1 100644
--- a/mesalib/src/mesa/main/format_unpack.h
+++ b/mesalib/src/mesa/main/format_unpack.h
@@ -28,10 +28,13 @@ extern void
_mesa_unpack_rgba_row(gl_format format, GLuint n,
const void *src, GLfloat dst[][4]);
+extern void
+_mesa_unpack_ubyte_rgba_row(gl_format format, GLuint n,
+ const void *src, GLubyte dst[][4]);
void
-_mesa_unpack_int_rgba_row(gl_format format, GLuint n,
- const void *src, GLuint dst[][4]);
+_mesa_unpack_uint_rgba_row(gl_format format, GLuint n,
+ const void *src, GLuint dst[][4]);
extern void
_mesa_unpack_rgba_block(gl_format format,
diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c
index cca0014b1..96317dbf4 100644
--- a/mesalib/src/mesa/main/formats.c
+++ b/mesalib/src/mesa/main/formats.c
@@ -1951,7 +1951,7 @@ _mesa_test_formats(void)
{
GLuint i;
- assert(Elements(format_info) == MESA_FORMAT_COUNT);
+ STATIC_ASSERT(Elements(format_info) == MESA_FORMAT_COUNT);
for (i = 0; i < MESA_FORMAT_COUNT; i++) {
const struct gl_format_info *info = _mesa_get_format_info(i);
diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c
index 38b9c64ed..0c0e5394d 100644
--- a/mesalib/src/mesa/main/readpix.c
+++ b/mesalib/src/mesa/main/readpix.c
@@ -273,7 +273,7 @@ slow_read_rgba_pixels( struct gl_context *ctx,
for (j = 0; j < height; j++) {
if (_mesa_is_integer_format(format)) {
- _mesa_unpack_int_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba);
+ _mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba);
_mesa_pack_rgba_span_int(ctx, width, (GLuint (*)[4]) rgba, format,
type, dst);
} else {
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index 52a9bd452..9372d6dec 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -923,7 +923,7 @@ validate_samplers(const struct gl_program *prog, char *errMsg)
GLbitfield samplersUsed = prog->SamplersUsed;
GLuint i;
- assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
+ STATIC_ASSERT(Elements(targetName) == NUM_TEXTURE_TARGETS);
if (samplersUsed == 0x0)
return GL_TRUE;
diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c
index 276fac149..c3e93b5a5 100644
--- a/mesalib/src/mesa/main/shared.c
+++ b/mesalib/src/mesa/main/shared.c
@@ -113,7 +113,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
GL_TEXTURE_2D,
GL_TEXTURE_1D
};
- assert(Elements(targets) == NUM_TEXTURE_TARGETS);
+ STATIC_ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]);
}
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index 7cd285803..8e9537fae 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -695,7 +695,7 @@ alloc_proxy_textures( struct gl_context *ctx )
};
GLint tgt;
- ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
+ STATIC_ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
if (!(ctx->Texture.ProxyTex[tgt]
diff --git a/mesalib/src/mesa/main/version.h b/mesalib/src/mesa/main/version.h
index 32e141f0e..d288c4d55 100644
--- a/mesalib/src/mesa/main/version.h
+++ b/mesalib/src/mesa/main/version.h
@@ -32,10 +32,10 @@ struct gl_context;
/* Mesa version */
-#define MESA_MAJOR 7
-#define MESA_MINOR 12
+#define MESA_MAJOR 8
+#define MESA_MINOR 0
#define MESA_PATCH 0
-#define MESA_VERSION_STRING "7.12-devel"
+#define MESA_VERSION_STRING "8.0-devel"
/* To make version comparison easy */
#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/mesalib/src/mesa/program/nvvertparse.c b/mesalib/src/mesa/program/nvvertparse.c
index 91fe2c48b..7b46bef91 100644
--- a/mesalib/src/mesa/program/nvvertparse.c
+++ b/mesalib/src/mesa/program/nvvertparse.c
@@ -1424,6 +1424,7 @@ _mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget,
index = _mesa_add_state_reference(program->Base.Parameters,
state_tokens);
assert(index == i);
+ (void)index;
}
program->Base.NumParameters = program->Base.Parameters->NumParameters;
diff --git a/mesalib/src/mesa/program/symbol_table.c b/mesalib/src/mesa/program/symbol_table.c
index 45aeb97b1..4f6f31f31 100644
--- a/mesalib/src/mesa/program/symbol_table.c
+++ b/mesalib/src/mesa/program/symbol_table.c
@@ -1,488 +1,489 @@
-/*
- * Copyright © 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "main/imports.h"
-#include "symbol_table.h"
-#include "hash_table.h"
-
-struct symbol {
- /**
- * Link to the next symbol in the table with the same name
- *
- * The linked list of symbols with the same name is ordered by scope
- * from inner-most to outer-most.
- */
- struct symbol *next_with_same_name;
-
-
- /**
- * Link to the next symbol in the table with the same scope
- *
- * The linked list of symbols with the same scope is unordered. Symbols
- * in this list my have unique names.
- */
- struct symbol *next_with_same_scope;
-
-
- /**
- * Header information for the list of symbols with the same name.
- */
- struct symbol_header *hdr;
-
-
- /**
- * Name space of the symbol
- *
- * Name space are arbitrary user assigned integers. No two symbols can
- * exist in the same name space at the same scope level.
- */
- int name_space;
-
- /** Scope depth where this symbol was defined. */
- unsigned depth;
-
- /**
- * Arbitrary user supplied data.
- */
- void *data;
-};
-
-
-/**
- */
-struct symbol_header {
- /** Linkage in list of all headers in a given symbol table. */
- struct symbol_header *next;
-
- /** Symbol name. */
- char *name;
-
- /** Linked list of symbols with the same name. */
- struct symbol *symbols;
-};
-
-
-/**
- * Element of the scope stack.
- */
-struct scope_level {
- /** Link to next (inner) scope level. */
- struct scope_level *next;
-
- /** Linked list of symbols with the same scope. */
- struct symbol *symbols;
-};
-
-
-/**
- *
- */
-struct _mesa_symbol_table {
- /** Hash table containing all symbols in the symbol table. */
- struct hash_table *ht;
-
- /** Top of scope stack. */
- struct scope_level *current_scope;
-
- /** List of all symbol headers in the table. */
- struct symbol_header *hdr;
-
- /** Current scope depth. */
- unsigned depth;
-};
-
-
-struct _mesa_symbol_table_iterator {
- /**
- * Name space of symbols returned by this iterator.
- */
- int name_space;
-
-
- /**
- * Currently iterated symbol
- *
- * The next call to \c _mesa_symbol_table_iterator_get will return this
- * value. It will also update this value to the value that should be
- * returned by the next call.
- */
- struct symbol *curr;
-};
-
-
-static void
-check_symbol_table(struct _mesa_symbol_table *table)
-{
-#if 1
- struct scope_level *scope;
-
- for (scope = table->current_scope; scope != NULL; scope = scope->next) {
- struct symbol *sym;
-
- for (sym = scope->symbols
- ; sym != NULL
- ; sym = sym->next_with_same_name) {
- const struct symbol_header *const hdr = sym->hdr;
- struct symbol *sym2;
-
- for (sym2 = hdr->symbols
- ; sym2 != NULL
- ; sym2 = sym2->next_with_same_name) {
- assert(sym2->hdr == hdr);
- }
- }
- }
-#endif
-}
-
-void
-_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
-{
- struct scope_level *const scope = table->current_scope;
- struct symbol *sym = scope->symbols;
-
- table->current_scope = scope->next;
- table->depth--;
-
- free(scope);
-
- while (sym != NULL) {
- struct symbol *const next = sym->next_with_same_scope;
- struct symbol_header *const hdr = sym->hdr;
-
- assert(hdr->symbols == sym);
-
- hdr->symbols = sym->next_with_same_name;
-
- free(sym);
-
- sym = next;
- }
-
- check_symbol_table(table);
-}
-
-
-void
-_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
-{
- struct scope_level *const scope = calloc(1, sizeof(*scope));
-
- scope->next = table->current_scope;
- table->current_scope = scope;
- table->depth++;
-}
-
-
-static struct symbol_header *
-find_symbol(struct _mesa_symbol_table *table, const char *name)
-{
- return (struct symbol_header *) hash_table_find(table->ht, name);
-}
-
-
-struct _mesa_symbol_table_iterator *
-_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
- struct symbol_header *const hdr = find_symbol(table, name);
-
- iter->name_space = name_space;
-
- if (hdr != NULL) {
- struct symbol *sym;
-
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- iter->curr = sym;
- break;
- }
- }
- }
-
- return iter;
-}
-
-
-void
-_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
-{
- free(iter);
-}
-
-
-void *
-_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
-{
- return (iter->curr == NULL) ? NULL : iter->curr->data;
-}
-
-
-int
-_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
-{
- struct symbol_header *hdr;
-
- if (iter->curr == NULL) {
- return 0;
- }
-
- hdr = iter->curr->hdr;
- iter->curr = iter->curr->next_with_same_name;
-
- while (iter->curr != NULL) {
- assert(iter->curr->hdr == hdr);
-
- if ((iter->name_space == -1)
- || (iter->curr->name_space == iter->name_space)) {
- return 1;
- }
-
- iter->curr = iter->curr->next_with_same_name;
- }
-
- return 0;
-}
-
-
-/**
- * Determine the scope "distance" of a symbol from the current scope
- *
- * \return
- * A non-negative number for the number of scopes between the current scope
- * and the scope where a symbol was defined. A value of zero means the current
- * scope. A negative number if the symbol does not exist.
- */
-int
-_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct symbol_header *const hdr = find_symbol(table, name);
- struct symbol *sym;
-
- if (hdr != NULL) {
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- assert(sym->depth <= table->depth);
- return sym->depth - table->depth;
- }
- }
- }
-
- return -1;
-}
-
-
-void *
-_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct symbol_header *const hdr = find_symbol(table, name);
-
- if (hdr != NULL) {
- struct symbol *sym;
-
-
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- return sym->data;
- }
- }
- }
-
- return NULL;
-}
-
-
-int
-_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name,
- void *declaration)
-{
- struct symbol_header *hdr;
- struct symbol *sym;
-
- check_symbol_table(table);
-
- hdr = find_symbol(table, name);
-
- check_symbol_table(table);
-
- if (hdr == NULL) {
- hdr = calloc(1, sizeof(*hdr));
- hdr->name = strdup(name);
-
- hash_table_insert(table->ht, hdr, hdr->name);
- hdr->next = table->hdr;
- table->hdr = hdr;
- }
-
- check_symbol_table(table);
-
- /* If the symbol already exists in this namespace at this scope, it cannot
- * be added to the table.
- */
- for (sym = hdr->symbols
- ; (sym != NULL) && (sym->name_space != name_space)
- ; sym = sym->next_with_same_name) {
- /* empty */
- }
-
- if (sym && (sym->depth == table->depth))
- return -1;
-
- sym = calloc(1, sizeof(*sym));
- sym->next_with_same_name = hdr->symbols;
- sym->next_with_same_scope = table->current_scope->symbols;
- sym->hdr = hdr;
- sym->name_space = name_space;
- sym->data = declaration;
- sym->depth = table->depth;
-
- assert(sym->hdr == hdr);
-
- hdr->symbols = sym;
- table->current_scope->symbols = sym;
-
- check_symbol_table(table);
- return 0;
-}
-
-
-int
-_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name,
- void *declaration)
-{
- struct symbol_header *hdr;
- struct symbol *sym;
- struct symbol *curr;
- struct scope_level *top_scope;
-
- check_symbol_table(table);
-
- hdr = find_symbol(table, name);
-
- check_symbol_table(table);
-
- if (hdr == NULL) {
- hdr = calloc(1, sizeof(*hdr));
- hdr->name = strdup(name);
-
- hash_table_insert(table->ht, hdr, hdr->name);
- hdr->next = table->hdr;
- table->hdr = hdr;
- }
-
- check_symbol_table(table);
-
- /* If the symbol already exists in this namespace at this scope, it cannot
- * be added to the table.
- */
- for (sym = hdr->symbols
- ; (sym != NULL) && (sym->name_space != name_space)
- ; sym = sym->next_with_same_name) {
- /* empty */
- }
-
- if (sym && sym->depth == 0)
- return -1;
-
- /* Find the top-level scope */
- for (top_scope = table->current_scope
- ; top_scope->next != NULL
- ; top_scope = top_scope->next) {
- /* empty */
- }
-
- sym = calloc(1, sizeof(*sym));
- sym->next_with_same_scope = top_scope->symbols;
- sym->hdr = hdr;
- sym->name_space = name_space;
- sym->data = declaration;
-
- assert(sym->hdr == hdr);
-
- /* Since next_with_same_name is ordered by scope, we need to append the
- * new symbol to the _end_ of the list.
- */
- if (hdr->symbols == NULL) {
- hdr->symbols = sym;
- } else {
- for (curr = hdr->symbols
- ; curr->next_with_same_name != NULL
- ; curr = curr->next_with_same_name) {
- /* empty */
- }
- curr->next_with_same_name = sym;
- }
- top_scope->symbols = sym;
-
- check_symbol_table(table);
- return 0;
-}
-
-
-
-struct _mesa_symbol_table *
-_mesa_symbol_table_ctor(void)
-{
- struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
-
- if (table != NULL) {
- table->ht = hash_table_ctor(32, hash_table_string_hash,
- hash_table_string_compare);
-
- _mesa_symbol_table_push_scope(table);
- }
-
- return table;
-}
-
-
-void
-_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
-{
- struct symbol_header *hdr;
- struct symbol_header *next;
-
- while (table->current_scope != NULL) {
- _mesa_symbol_table_pop_scope(table);
- }
-
- for (hdr = table->hdr; hdr != NULL; hdr = next) {
- next = hdr->next;
- free(hdr->name);
- free(hdr);
- }
-
- hash_table_dtor(table->ht);
- free(table);
-}
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "main/imports.h"
+#include "symbol_table.h"
+#include "hash_table.h"
+
+struct symbol {
+ /**
+ * Link to the next symbol in the table with the same name
+ *
+ * The linked list of symbols with the same name is ordered by scope
+ * from inner-most to outer-most.
+ */
+ struct symbol *next_with_same_name;
+
+
+ /**
+ * Link to the next symbol in the table with the same scope
+ *
+ * The linked list of symbols with the same scope is unordered. Symbols
+ * in this list my have unique names.
+ */
+ struct symbol *next_with_same_scope;
+
+
+ /**
+ * Header information for the list of symbols with the same name.
+ */
+ struct symbol_header *hdr;
+
+
+ /**
+ * Name space of the symbol
+ *
+ * Name space are arbitrary user assigned integers. No two symbols can
+ * exist in the same name space at the same scope level.
+ */
+ int name_space;
+
+ /** Scope depth where this symbol was defined. */
+ unsigned depth;
+
+ /**
+ * Arbitrary user supplied data.
+ */
+ void *data;
+};
+
+
+/**
+ */
+struct symbol_header {
+ /** Linkage in list of all headers in a given symbol table. */
+ struct symbol_header *next;
+
+ /** Symbol name. */
+ char *name;
+
+ /** Linked list of symbols with the same name. */
+ struct symbol *symbols;
+};
+
+
+/**
+ * Element of the scope stack.
+ */
+struct scope_level {
+ /** Link to next (inner) scope level. */
+ struct scope_level *next;
+
+ /** Linked list of symbols with the same scope. */
+ struct symbol *symbols;
+};
+
+
+/**
+ *
+ */
+struct _mesa_symbol_table {
+ /** Hash table containing all symbols in the symbol table. */
+ struct hash_table *ht;
+
+ /** Top of scope stack. */
+ struct scope_level *current_scope;
+
+ /** List of all symbol headers in the table. */
+ struct symbol_header *hdr;
+
+ /** Current scope depth. */
+ unsigned depth;
+};
+
+
+struct _mesa_symbol_table_iterator {
+ /**
+ * Name space of symbols returned by this iterator.
+ */
+ int name_space;
+
+
+ /**
+ * Currently iterated symbol
+ *
+ * The next call to \c _mesa_symbol_table_iterator_get will return this
+ * value. It will also update this value to the value that should be
+ * returned by the next call.
+ */
+ struct symbol *curr;
+};
+
+
+static void
+check_symbol_table(struct _mesa_symbol_table *table)
+{
+#if 1
+ struct scope_level *scope;
+
+ for (scope = table->current_scope; scope != NULL; scope = scope->next) {
+ struct symbol *sym;
+
+ for (sym = scope->symbols
+ ; sym != NULL
+ ; sym = sym->next_with_same_name) {
+ const struct symbol_header *const hdr = sym->hdr;
+ struct symbol *sym2;
+
+ for (sym2 = hdr->symbols
+ ; sym2 != NULL
+ ; sym2 = sym2->next_with_same_name) {
+ assert(sym2->hdr == hdr);
+ }
+ }
+ }
+#endif
+}
+
+void
+_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = table->current_scope;
+ struct symbol *sym = scope->symbols;
+
+ table->current_scope = scope->next;
+ table->depth--;
+
+ free(scope);
+
+ while (sym != NULL) {
+ struct symbol *const next = sym->next_with_same_scope;
+ struct symbol_header *const hdr = sym->hdr;
+
+ assert(hdr->symbols == sym);
+
+ hdr->symbols = sym->next_with_same_name;
+
+ free(sym);
+
+ sym = next;
+ }
+
+ check_symbol_table(table);
+}
+
+
+void
+_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = calloc(1, sizeof(*scope));
+
+ scope->next = table->current_scope;
+ table->current_scope = scope;
+ table->depth++;
+}
+
+
+static struct symbol_header *
+find_symbol(struct _mesa_symbol_table *table, const char *name)
+{
+ return (struct symbol_header *) hash_table_find(table->ht, name);
+}
+
+
+struct _mesa_symbol_table_iterator *
+_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
+ struct symbol_header *const hdr = find_symbol(table, name);
+
+ iter->name_space = name_space;
+
+ if (hdr != NULL) {
+ struct symbol *sym;
+
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ iter->curr = sym;
+ break;
+ }
+ }
+ }
+
+ return iter;
+}
+
+
+void
+_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
+{
+ free(iter);
+}
+
+
+void *
+_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
+{
+ return (iter->curr == NULL) ? NULL : iter->curr->data;
+}
+
+
+int
+_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
+{
+ struct symbol_header *hdr;
+
+ if (iter->curr == NULL) {
+ return 0;
+ }
+
+ hdr = iter->curr->hdr;
+ iter->curr = iter->curr->next_with_same_name;
+
+ while (iter->curr != NULL) {
+ assert(iter->curr->hdr == hdr);
+ (void)hdr;
+
+ if ((iter->name_space == -1)
+ || (iter->curr->name_space == iter->name_space)) {
+ return 1;
+ }
+
+ iter->curr = iter->curr->next_with_same_name;
+ }
+
+ return 0;
+}
+
+
+/**
+ * Determine the scope "distance" of a symbol from the current scope
+ *
+ * \return
+ * A non-negative number for the number of scopes between the current scope
+ * and the scope where a symbol was defined. A value of zero means the current
+ * scope. A negative number if the symbol does not exist.
+ */
+int
+_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+ struct symbol *sym;
+
+ if (hdr != NULL) {
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ assert(sym->depth <= table->depth);
+ return sym->depth - table->depth;
+ }
+ }
+ }
+
+ return -1;
+}
+
+
+void *
+_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+
+ if (hdr != NULL) {
+ struct symbol *sym;
+
+
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ return sym->data;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+int
+_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name,
+ void *declaration)
+{
+ struct symbol_header *hdr;
+ struct symbol *sym;
+
+ check_symbol_table(table);
+
+ hdr = find_symbol(table, name);
+
+ check_symbol_table(table);
+
+ if (hdr == NULL) {
+ hdr = calloc(1, sizeof(*hdr));
+ hdr->name = strdup(name);
+
+ hash_table_insert(table->ht, hdr, hdr->name);
+ hdr->next = table->hdr;
+ table->hdr = hdr;
+ }
+
+ check_symbol_table(table);
+
+ /* If the symbol already exists in this namespace at this scope, it cannot
+ * be added to the table.
+ */
+ for (sym = hdr->symbols
+ ; (sym != NULL) && (sym->name_space != name_space)
+ ; sym = sym->next_with_same_name) {
+ /* empty */
+ }
+
+ if (sym && (sym->depth == table->depth))
+ return -1;
+
+ sym = calloc(1, sizeof(*sym));
+ sym->next_with_same_name = hdr->symbols;
+ sym->next_with_same_scope = table->current_scope->symbols;
+ sym->hdr = hdr;
+ sym->name_space = name_space;
+ sym->data = declaration;
+ sym->depth = table->depth;
+
+ assert(sym->hdr == hdr);
+
+ hdr->symbols = sym;
+ table->current_scope->symbols = sym;
+
+ check_symbol_table(table);
+ return 0;
+}
+
+
+int
+_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name,
+ void *declaration)
+{
+ struct symbol_header *hdr;
+ struct symbol *sym;
+ struct symbol *curr;
+ struct scope_level *top_scope;
+
+ check_symbol_table(table);
+
+ hdr = find_symbol(table, name);
+
+ check_symbol_table(table);
+
+ if (hdr == NULL) {
+ hdr = calloc(1, sizeof(*hdr));
+ hdr->name = strdup(name);
+
+ hash_table_insert(table->ht, hdr, hdr->name);
+ hdr->next = table->hdr;
+ table->hdr = hdr;
+ }
+
+ check_symbol_table(table);
+
+ /* If the symbol already exists in this namespace at this scope, it cannot
+ * be added to the table.
+ */
+ for (sym = hdr->symbols
+ ; (sym != NULL) && (sym->name_space != name_space)
+ ; sym = sym->next_with_same_name) {
+ /* empty */
+ }
+
+ if (sym && sym->depth == 0)
+ return -1;
+
+ /* Find the top-level scope */
+ for (top_scope = table->current_scope
+ ; top_scope->next != NULL
+ ; top_scope = top_scope->next) {
+ /* empty */
+ }
+
+ sym = calloc(1, sizeof(*sym));
+ sym->next_with_same_scope = top_scope->symbols;
+ sym->hdr = hdr;
+ sym->name_space = name_space;
+ sym->data = declaration;
+
+ assert(sym->hdr == hdr);
+
+ /* Since next_with_same_name is ordered by scope, we need to append the
+ * new symbol to the _end_ of the list.
+ */
+ if (hdr->symbols == NULL) {
+ hdr->symbols = sym;
+ } else {
+ for (curr = hdr->symbols
+ ; curr->next_with_same_name != NULL
+ ; curr = curr->next_with_same_name) {
+ /* empty */
+ }
+ curr->next_with_same_name = sym;
+ }
+ top_scope->symbols = sym;
+
+ check_symbol_table(table);
+ return 0;
+}
+
+
+
+struct _mesa_symbol_table *
+_mesa_symbol_table_ctor(void)
+{
+ struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
+
+ if (table != NULL) {
+ table->ht = hash_table_ctor(32, hash_table_string_hash,
+ hash_table_string_compare);
+
+ _mesa_symbol_table_push_scope(table);
+ }
+
+ return table;
+}
+
+
+void
+_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
+{
+ struct symbol_header *hdr;
+ struct symbol_header *next;
+
+ while (table->current_scope != NULL) {
+ _mesa_symbol_table_pop_scope(table);
+ }
+
+ for (hdr = table->hdr; hdr != NULL; hdr = next) {
+ next = hdr->next;
+ free(hdr->name);
+ free(hdr);
+ }
+
+ hash_table_dtor(table->ht);
+ free(table);
+}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_clip.c b/mesalib/src/mesa/state_tracker/st_atom_clip.c
index 236d3cf40..2a5110098 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_clip.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_clip.c
@@ -35,6 +35,7 @@
#include "pipe/p_context.h"
#include "st_atom.h"
#include "st_program.h"
+#include "util/u_debug.h"
#include "cso_cache/cso_context.h"
@@ -44,10 +45,9 @@ static void update_clip( struct st_context *st )
{
struct pipe_clip_state clip;
const struct gl_context *ctx = st->ctx;
- GLuint i;
bool use_eye = FALSE;
- memset(&clip, 0, sizeof(clip));
+ assert(sizeof(clip.ucp) <= sizeof(ctx->Transform._ClipUserPlane));
/* if we have a vertex shader that writes clip vertex we need to pass
the pre-projection transformed coordinates into the driver. */
@@ -56,21 +56,11 @@ static void update_clip( struct st_context *st )
use_eye = TRUE;
}
- for (i = 0; i < PIPE_MAX_CLIP_PLANES; i++) {
- if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
- memcpy(clip.ucp[clip.nr],
- use_eye ? ctx->Transform.EyeUserPlane[i] : ctx->Transform._ClipUserPlane[i],
- sizeof(clip.ucp[0]));
- clip.nr++;
- }
- }
-
- clip.depth_clamp = ctx->Transform.DepthClamp != GL_FALSE;
-
- if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) {
- st->state.clip = clip;
- cso_set_clip(st->cso_context, &clip);
- }
+ memcpy(clip.ucp,
+ use_eye ? ctx->Transform.EyeUserPlane
+ : ctx->Transform._ClipUserPlane, sizeof(clip.ucp));
+ st->state.clip = clip;
+ cso_set_clip(st->cso_context, &clip);
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
index 2d6ad45ba..f3d28e675 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -261,6 +261,10 @@ static void update_raster_state( struct st_context *st )
/* _NEW_RASTERIZER_DISCARD */
raster->rasterizer_discard = ctx->RasterDiscard;
+ /* _NEW_TRANSFORM */
+ raster->depth_clip = ctx->Transform.DepthClamp == GL_FALSE;
+ raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled;
+
cso_set_rasterizer(st->cso_context, raster);
}
@@ -276,7 +280,8 @@ const struct st_tracked_state st_update_rasterizer = {
_NEW_PROGRAM |
_NEW_SCISSOR |
_NEW_FRAG_CLAMP |
- _NEW_RASTERIZER_DISCARD), /* mesa state dependencies*/
+ _NEW_RASTERIZER_DISCARD |
+ _NEW_TRANSFORM), /* mesa state dependencies*/
ST_NEW_VERTEX_PROGRAM, /* state tracker dependencies */
},
update_raster_state /* update function */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
index af33bcf86..a97096802 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
@@ -870,6 +870,7 @@ st_init_bitmap(struct st_context *st)
/* init baseline rasterizer state once */
memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
st->bitmap.rasterizer.gl_rasterization_rules = 1;
+ st->bitmap.rasterizer.depth_clip = 1;
/* find a usable texture format */
if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM,
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index 23700eeb7..a8365a708 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -68,6 +68,7 @@ st_init_clear(struct st_context *st)
memset(&st->clear, 0, sizeof(st->clear));
st->clear.raster.gl_rasterization_rules = 1;
+ st->clear.raster.depth_clip = 1;
st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
}
@@ -248,7 +249,6 @@ clear_with_quad(struct gl_context *ctx,
cso_save_depth_stencil_alpha(st->cso_context);
cso_save_rasterizer(st->cso_context);
cso_save_viewport(st->cso_context);
- cso_save_clip(st->cso_context);
cso_save_fragment_shader(st->cso_context);
cso_save_stream_outputs(st->cso_context);
cso_save_vertex_shader(st->cso_context);
@@ -326,7 +326,6 @@ clear_with_quad(struct gl_context *ctx,
cso_set_viewport(st->cso_context, &vp);
}
- cso_set_clip(st->cso_context, &st->clear.clip);
set_fragment_shader(st);
set_vertex_shader(st);
cso_set_geometry_shader_handle(st->cso_context, NULL);
@@ -346,7 +345,6 @@ clear_with_quad(struct gl_context *ctx,
cso_restore_depth_stencil_alpha(st->cso_context);
cso_restore_rasterizer(st->cso_context);
cso_restore_viewport(st->cso_context);
- cso_restore_clip(st->cso_context);
cso_restore_fragment_shader(st->cso_context);
cso_restore_vertex_shader(st->cso_context);
cso_restore_geometry_shader(st->cso_context);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
index 0609a54ea..13c4f3369 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -686,6 +686,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
memset(&rasterizer, 0, sizeof(rasterizer));
rasterizer.clamp_fragment_color = ctx->Color._ClampFragmentColor;
rasterizer.gl_rasterization_rules = 1;
+ rasterizer.depth_clip = !ctx->Transform.DepthClamp;
rasterizer.scissor = ctx->Scissor.Enabled;
cso_set_rasterizer(cso, &rasterizer);
}
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h
index c60780989..9db50b3f4 100644
--- a/mesalib/src/mesa/state_tracker/st_context.h
+++ b/mesalib/src/mesa/state_tracker/st_context.h
@@ -167,7 +167,6 @@ struct st_context
struct {
struct pipe_rasterizer_state raster;
struct pipe_viewport_state viewport;
- struct pipe_clip_state clip;
void *vs;
void *fs;
float vertices[4][2][4]; /**< vertex pos + color */
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 4c8c67fca..a9d405436 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -592,7 +592,7 @@ void st_init_extensions(struct st_context *st)
st->sw_primitive_restart = GL_TRUE;
}
- if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
+ if (screen->get_param(screen, PIPE_CAP_DEPTH_CLIP_DISABLE)) {
ctx->Extensions.ARB_depth_clamp = GL_TRUE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c
index c0af3ce11..b83cb2339 100644
--- a/mesalib/src/mesa/state_tracker/st_manager.c
+++ b/mesalib/src/mesa/state_tracker/st_manager.c
@@ -222,7 +222,6 @@ st_framebuffer_validate(struct st_framebuffer *stfb,
continue;
}
- memset(&surf_tmpl, 0, sizeof(surf_tmpl));
u_surface_default_template(&surf_tmpl, textures[i],
PIPE_BIND_RENDER_TARGET);
ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl);
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index 8d7469dfb..8d08b2b0f 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -441,7 +441,7 @@ st_translate_interp(enum glsl_interp_qualifier glsl_qual, bool is_color)
switch (glsl_qual) {
case INTERP_QUALIFIER_NONE:
if (is_color)
- return TGSI_INTERPOLATE_LINEAR;
+ return TGSI_INTERPOLATE_COLOR;
return TGSI_INTERPOLATE_PERSPECTIVE;
case INTERP_QUALIFIER_SMOOTH:
return TGSI_INTERPOLATE_PERSPECTIVE;
diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c
index 1063024fb..6d0b889c1 100644
--- a/mesalib/src/mesa/swrast/s_blit.c
+++ b/mesalib/src/mesa/swrast/s_blit.c
@@ -423,9 +423,66 @@ resample_linear_row_ub(GLint srcWidth, GLint dstWidth,
}
+/**
+ * Bilinear interpolation of two source rows. floating point pixels.
+ */
+static void
+resample_linear_row_float(GLint srcWidth, GLint dstWidth,
+ const GLvoid *srcBuffer0, const GLvoid *srcBuffer1,
+ GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight)
+{
+ const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0;
+ const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1;
+ GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer;
+ const GLfloat dstWidthF = (GLfloat) dstWidth;
+ GLint dstCol;
+
+ for (dstCol = 0; dstCol < dstWidth; dstCol++) {
+ const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF;
+ GLint srcCol0 = IFLOOR(srcCol);
+ GLint srcCol1 = srcCol0 + 1;
+ GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */
+ GLfloat red, green, blue, alpha;
+
+ ASSERT(srcCol0 >= 0);
+ ASSERT(srcCol0 < srcWidth);
+ ASSERT(srcCol1 <= srcWidth);
+
+ if (srcCol1 == srcWidth) {
+ /* last column fudge */
+ srcCol1--;
+ colWeight = 0.0;
+ }
+
+ if (flip) {
+ srcCol0 = srcWidth - 1 - srcCol0;
+ srcCol1 = srcWidth - 1 - srcCol1;
+ }
+
+ red = lerp_2d(colWeight, rowWeight,
+ srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP],
+ srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]);
+ green = lerp_2d(colWeight, rowWeight,
+ srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP],
+ srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]);
+ blue = lerp_2d(colWeight, rowWeight,
+ srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP],
+ srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]);
+ alpha = lerp_2d(colWeight, rowWeight,
+ srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP],
+ srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]);
+
+ dstColor[dstCol][RCOMP] = red;
+ dstColor[dstCol][GCOMP] = green;
+ dstColor[dstCol][BCOMP] = blue;
+ dstColor[dstCol][ACOMP] = alpha;
+ }
+}
+
+
/**
- * Bilinear filtered blit (color only).
+ * Bilinear filtered blit (color only, non-integer values).
*/
static void
blit_linear(struct gl_context *ctx,
@@ -456,23 +513,25 @@ blit_linear(struct gl_context *ctx,
GLint srcBufferY0 = -1, srcBufferY1 = -1;
GLvoid *dstBuffer;
- switch (readRb->DataType) {
- case GL_UNSIGNED_BYTE:
+ gl_format readFormat = _mesa_get_srgb_format_linear(readRb->Format);
+ gl_format drawFormat = _mesa_get_srgb_format_linear(drawRb->Format);
+ GLuint bpp = _mesa_get_format_bytes(readFormat);
+
+ GLenum pixelType;
+
+ GLubyte *srcMap, *dstMap;
+ GLint srcRowStride, dstRowStride;
+
+
+ /* Determine datatype for resampling */
+ if (_mesa_get_format_max_bits(readFormat) == 8 &&
+ _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) {
+ pixelType = GL_UNSIGNED_BYTE;
pixelSize = 4 * sizeof(GLubyte);
- break;
- case GL_UNSIGNED_SHORT:
- pixelSize = 4 * sizeof(GLushort);
- break;
- case GL_UNSIGNED_INT:
- pixelSize = 4 * sizeof(GLuint);
- break;
- case GL_FLOAT:
+ }
+ else {
+ pixelType = GL_FLOAT;
pixelSize = 4 * sizeof(GLfloat);
- break;
- default:
- _mesa_problem(ctx, "unexpected buffer type (0x%x) in blit_nearest",
- readRb->DataType);
- return;
}
/* Allocate the src/dst row buffers.
@@ -497,6 +556,45 @@ blit_linear(struct gl_context *ctx,
return;
}
+ /*
+ * Map src / dst renderbuffers
+ */
+ if (readRb == drawRb) {
+ /* map whole buffer for read/write */
+ ctx->Driver.MapRenderbuffer(ctx, readRb,
+ 0, 0, readRb->Width, readRb->Height,
+ GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
+ &srcMap, &srcRowStride);
+ if (!srcMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
+ return;
+ }
+
+ dstMap = srcMap;
+ dstRowStride = srcRowStride;
+ }
+ else {
+ /* different src/dst buffers */
+ /* XXX with a bit of work we could just map the regions to be
+ * read/written instead of the whole buffers.
+ */
+ ctx->Driver.MapRenderbuffer(ctx, readRb,
+ 0, 0, readRb->Width, readRb->Height,
+ GL_MAP_READ_BIT, &srcMap, &srcRowStride);
+ if (!srcMap) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
+ return;
+ }
+ ctx->Driver.MapRenderbuffer(ctx, drawRb,
+ 0, 0, drawRb->Width, drawRb->Height,
+ GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
+ if (!dstMap) {
+ ctx->Driver.UnmapRenderbuffer(ctx, readRb);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
+ return;
+ }
+ }
+
for (dstRow = 0; dstRow < dstHeight; dstRow++) {
const GLint dstY = dstYpos + dstRow;
const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF;
@@ -531,36 +629,73 @@ blit_linear(struct gl_context *ctx,
srcBuffer0 = srcBuffer1;
srcBuffer1 = tmp;
/* get y1 row */
- readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY1, srcBuffer1);
+ {
+ GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
+ if (pixelType == GL_UNSIGNED_BYTE) {
+ _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
+ src, srcBuffer1);
+ }
+ else {
+ _mesa_unpack_rgba_row(readFormat, srcWidth,
+ src, srcBuffer1);
+ }
+ }
srcBufferY0 = srcY0;
srcBufferY1 = srcY1;
}
else {
/* get both new rows */
- readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY0, srcBuffer0);
- readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY1, srcBuffer1);
+ {
+ GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp;
+ GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
+ if (pixelType == GL_UNSIGNED_BYTE) {
+ _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
+ src0, srcBuffer0);
+ _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
+ src1, srcBuffer1);
+ }
+ else {
+ _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0);
+ _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1);
+ }
+ }
srcBufferY0 = srcY0;
srcBufferY1 = srcY1;
}
- if (readRb->DataType == GL_UNSIGNED_BYTE) {
+ if (pixelType == GL_UNSIGNED_BYTE) {
resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
dstBuffer, invertX, rowWeight);
}
else {
- _mesa_problem(ctx, "Unsupported color channel type in sw blit");
- break;
+ resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
+ dstBuffer, invertX, rowWeight);
}
/* store pixel row in destination */
- drawRb->PutRow(ctx, drawRb, dstWidth, dstXpos, dstY, dstBuffer, NULL);
+ {
+ GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp;
+ if (pixelType == GL_UNSIGNED_BYTE) {
+ _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
+ }
+ else {
+ _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
+ }
+ }
}
free(srcBuffer0);
free(srcBuffer1);
free(dstBuffer);
+
+ ctx->Driver.UnmapRenderbuffer(ctx, readRb);
+ if (drawRb != readRb) {
+ ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
+ }
}
+
+
/**
* Software fallback for glBlitFramebufferEXT().
*/
@@ -626,10 +761,8 @@ _swrast_BlitFramebuffer(struct gl_context *ctx,
else {
ASSERT(filter == GL_LINEAR);
if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */
- swrast_render_start(ctx);
blit_linear(ctx, srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1);
- swrast_render_finish(ctx);
}
}