aboutsummaryrefslogtreecommitdiff
path: root/mesalib
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-10-26 10:58:41 +0200
committermarha <marha@users.sourceforge.net>2011-10-26 10:58:41 +0200
commit4f005bade376d15ee60e90ca45a831aff9725087 (patch)
tree5abdbe5a7c55acf9e30c533414796f629fa9e47c /mesalib
parent9f986778bd4393c5a9108426969d45aa7f10f334 (diff)
downloadvcxsrv-4f005bade376d15ee60e90ca45a831aff9725087.tar.gz
vcxsrv-4f005bade376d15ee60e90ca45a831aff9725087.tar.bz2
vcxsrv-4f005bade376d15ee60e90ca45a831aff9725087.zip
libX11 libXft mesa mkfontscale pixman xserver git update 26 okt 2011
Diffstat (limited to 'mesalib')
-rw-r--r--mesalib/configs/linux-dri6
-rw-r--r--mesalib/configure.ac2
-rw-r--r--mesalib/docs/contents.html1
-rw-r--r--mesalib/docs/relnotes-7.12.html2
-rw-r--r--mesalib/docs/viewperf.html134
-rw-r--r--mesalib/include/GL/gl.h2
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c286
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.h24
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_upload_mgr.c36
-rw-r--r--mesalib/src/glsl/Makefile1
-rw-r--r--mesalib/src/glsl/SConscript1
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp23
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp29
-rw-r--r--mesalib/src/glsl/ir_optimization.h6
-rw-r--r--mesalib/src/glsl/ir_variable.cpp8
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp85
-rw-r--r--mesalib/src/glsl/linker.cpp28
-rw-r--r--mesalib/src/glsl/linker.h43
-rw-r--r--mesalib/src/glsl/lower_if_to_cond_assign.cpp3
-rw-r--r--mesalib/src/glsl/main.cpp2
-rw-r--r--mesalib/src/glsl/opt_dead_code.cpp14
-rw-r--r--mesalib/src/glsl/ralloc.c28
-rw-r--r--mesalib/src/glsl/ralloc.h57
-rw-r--r--mesalib/src/glsl/test_optpass.cpp4
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c5
-rw-r--r--mesalib/src/mesa/main/APIspec.xml6
-rw-r--r--mesalib/src/mesa/main/attrib.c223
-rw-r--r--mesalib/src/mesa/main/bufferobj.c13
-rw-r--r--mesalib/src/mesa/main/compiler.h2
-rw-r--r--mesalib/src/mesa/main/context.h4
-rw-r--r--mesalib/src/mesa/main/dlist.c2
-rw-r--r--mesalib/src/mesa/main/fbobject.c8
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp2
-rw-r--r--mesalib/src/mesa/main/imports.c2
-rw-r--r--mesalib/src/mesa/main/imports.h8
-rw-r--r--mesalib/src/mesa/main/mtypes.h6
-rw-r--r--mesalib/src/mesa/main/pack.c1
-rw-r--r--mesalib/src/mesa/main/pixelstore.c2
-rw-r--r--mesalib/src/mesa/main/state.c2
-rw-r--r--mesalib/src/mesa/main/texcompress.c4
-rw-r--r--mesalib/src/mesa/main/texcompress_fxt1.c4
-rw-r--r--mesalib/src/mesa/main/texcompress_rgtc.c24
-rw-r--r--mesalib/src/mesa/main/texcompress_s3tc.c18
-rw-r--r--mesalib/src/mesa/main/texformat.c4
-rw-r--r--mesalib/src/mesa/main/teximage.c73
-rw-r--r--mesalib/src/mesa/main/teximage.h11
-rw-r--r--mesalib/src/mesa/main/texobj.c41
-rw-r--r--mesalib/src/mesa/main/texstore.c1
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp56
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c245
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c5
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp138
-rw-r--r--mesalib/src/mesa/swrast/s_context.c24
-rw-r--r--mesalib/src/mesa/swrast/s_context.h42
-rw-r--r--mesalib/src/mesa/swrast/s_fragprog.c3
-rw-r--r--mesalib/src/mesa/swrast/s_span.c5
-rw-r--r--mesalib/src/mesa/swrast/s_texcombine.c1
-rw-r--r--mesalib/src/mesa/swrast/s_texfetch_tmp.h8
-rw-r--r--mesalib/src/mesa/swrast/s_texfilter.c6
-rw-r--r--mesalib/src/mesa/swrast/s_texrender.c31
-rw-r--r--mesalib/src/mesa/swrast/s_texture.c175
-rw-r--r--mesalib/src/mesa/swrast/s_triangle.c18
-rw-r--r--mesalib/src/mesa/tnl/t_vb_program.c2
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec.h9
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c7
-rw-r--r--mesalib/src/mesa/vbo/vbo_save.h1
67 files changed, 1467 insertions, 601 deletions
diff --git a/mesalib/configs/linux-dri b/mesalib/configs/linux-dri
index a3e9baba2..aa2dddc1c 100644
--- a/mesalib/configs/linux-dri
+++ b/mesalib/configs/linux-dri
@@ -58,9 +58,9 @@ SRC_DIRS := glx egl $(SRC_DIRS)
EGL_DRIVERS_DIRS = glx
DRIVER_DIRS = dri
-GALLIUM_WINSYS_DIRS = sw sw/xlib drm/vmware drm/intel drm/i965
-GALLIUM_TARGET_DIRS =
-GALLIUM_STATE_TRACKERS_DIRS = egl
+GALLIUM_WINSYS_DIRS = sw sw/xlib drm/vmware drm/intel drm/i965 svga/drm
+GALLIUM_TARGET_DIRS = dri-vmwgfx
+GALLIUM_STATE_TRACKERS_DIRS = egl dri
DRI_DIRS = i915 i965 nouveau r200 r300 r600 radeon swrast
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 0864b55af..369614528 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -1858,7 +1858,7 @@ if test "x$with_gallium_drivers" != x; then
xnouveau)
PKG_CHECK_MODULES([NOUVEAU], [libdrm_nouveau >= $LIBDRM_NOUVEAU_REQUIRED])
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0"
- gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau"
+ gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau" "vdpau-nouveau"
;;
xswrast)
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS softpipe"
diff --git a/mesalib/docs/contents.html b/mesalib/docs/contents.html
index df0fb6474..8882e7318 100644
--- a/mesalib/docs/contents.html
+++ b/mesalib/docs/contents.html
@@ -64,6 +64,7 @@ a:visited {
<LI><A HREF="mangling.html" target="MainFrame">Function Name Mangling</A>
<LI><A href="llvmpipe.html" target="MainFrame">Gallium llvmpipe driver</A>
<LI><A href="postprocess.html" target="MainFrame">Gallium post-processing</A>
+<LI><A href="viewperf.html" target="MainFrame">Viewperf Issues</A>
</ul>
<b>Developer Topics</b>
diff --git a/mesalib/docs/relnotes-7.12.html b/mesalib/docs/relnotes-7.12.html
index 4077dac49..514962112 100644
--- a/mesalib/docs/relnotes-7.12.html
+++ b/mesalib/docs/relnotes-7.12.html
@@ -36,7 +36,7 @@ tbd
<h2>New features</h2>
<ul>
-<li>GL_ARB_ES2_compatibility (r600g)
+<li>GL_ARB_ES2_compatibility (r300g, r600g)
<li>GL_ARB_depth_buffer_float (r600g)
<li>GL_ARB_vertex_type_2_10_10_10_rev (r600g)
<li>GL_EXT_packed_float (i965)
diff --git a/mesalib/docs/viewperf.html b/mesalib/docs/viewperf.html
new file mode 100644
index 000000000..cef584fd8
--- /dev/null
+++ b/mesalib/docs/viewperf.html
@@ -0,0 +1,134 @@
+<HTML>
+
+<TITLE>Viewperf Issues</TITLE>
+
+<link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<h1>Viewperf Issues</h1>
+
+<p>
+This page lists known issues with
+<a href="http://www.spec.org/gwpg/gpc.static/vp11info.html" target="_main">SPEC Viewperf 11</a>
+when running on Mesa-based drivers.
+</p>
+
+<p>
+The Viewperf data sets are basically GL API traces that are recorded from
+CAD applications, then replayed in the Viewperf framework.
+</p>
+
+<p>
+The primary problem with these traces is they blindly use features and
+OpenGL extensions that were supported by the OpenGL driver when the trace
+was recorded,
+but there's no checks to see if those features are supported by the driver
+when playing back the traces with Viewperf.
+</p>
+
+<p>
+These issues have been reported to the SPEC organization in the hope that
+they'll be fixed in the future.
+</p>
+
+
+
+<h2>Catia-03 tests 3, 4, 8</h2>
+
+<p>
+These tests use features of the
+<a href="http://www.opengl.org/registry/specs/NV/fragment_program2.txt"
+target="_main">
+GL_NV_fragment_program2</a> and
+<a href="http://www.opengl.org/registry/specs/NV/vertex_program3.txt"
+target="_main">
+GL_NV_vertex_program3</a> extensions without checking if the driver supports
+them.
+</p>
+<p>
+When Mesa tries to compile the vertex/fragment programs it generates errors
+(which Viewperf ignores).
+Subsequent drawing calls become no-ops and the rendering is incorrect.
+</p>
+
+
+
+<h2>sw-02 tests 1, 2, 4</h2>
+
+<p>
+These tests depend on the
+<a href="http://www.opengl.org/registry/specs/NV/primitive_restart.txt"
+target="_main">GL_NV_primitive_restart</a> extension.
+</p>
+
+<p>
+If the Mesa driver doesn't support this extension the rendering will
+be incorrect and the test will fail.
+</p>
+
+
+<h2>Lightwave-01 test 3</h2>
+
+<p>
+This test uses a number of mipmapped textures, but the textures are
+incomplete because the last/smallest mipmap level (1 x 1 pixel) is
+never specified.
+</p>
+
+<p>
+A trace captured with
+<a href="https://github.com/apitrace/apitrace" target="_main">API trace</a>
+shows this sequences of calls like this:
+
+<pre>
+2504 glBindTexture(target = GL_TEXTURE_2D, texture = 55)
+2505 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_RGBA, width = 512, height = 512, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(1572864))
+2506 glTexImage2D(target = GL_TEXTURE_2D, level = 1, internalformat = GL_RGBA, width = 256, height = 256, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(393216))
+2507 glTexImage2D(target = GL_TEXTURE_2D, level = 2, internalformat = GL_RGBA, width = 128, height = 128, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(98304))
+[...]
+2512 glTexImage2D(target = GL_TEXTURE_2D, level = 7, internalformat = GL_RGBA, width = 4, height = 4, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(96))
+2513 glTexImage2D(target = GL_TEXTURE_2D, level = 8, internalformat = GL_RGBA, width = 2, height = 2, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(24))
+2514 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MIN_FILTER, param = GL_LINEAR_MIPMAP_LINEAR)
+2515 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_S, param = GL_REPEAT)
+2516 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_T, param = GL_REPEAT)
+2517 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MAG_FILTER, param = GL_NEAREST)
+</pre>
+
+<p>
+Note that one would expect call 2514 to be glTexImage(level=9, width=1,
+height=1) but it's not there.
+</p>
+
+<p>
+The minification filter is GL_LINEAR_MIPMAP_LINEAR and the texture's
+GL_TEXTURE_MAX_LEVEL is 1000 (the default) so a full mipmap is expected.
+</p>
+
+<p>
+Later, these incomplete textures are bound before drawing calls.
+According to the GL specification, if a fragment program or fragment shader
+is being used, the sampler should return (0,0,0,1) ("black") when sampling
+from an incomplete texture.
+This is what Mesa does and the resulting rendering is darker than it should
+be.
+</p>
+
+<p>
+It appears that NVIDIA's driver (and possibly AMD's driver) detects this case
+and returns (1,1,1,1) (white) which causes the rendering to appear brighter
+and match the reference image (however, AMD's rendering is <em>much</em>
+brighter than NVIDIA's).
+</p>
+
+<p>
+If the fallback texture created in _mesa_get_fallback_texture() is
+initialized to be full white instead of full black the rendering appears
+correct.
+However, we have no plans to implement this work-around in Mesa.
+
+</p>
+
+
+</BODY>
+</HTML>
diff --git a/mesalib/include/GL/gl.h b/mesalib/include/GL/gl.h
index 998a83ab1..e65e1bc8a 100644
--- a/mesalib/include/GL/gl.h
+++ b/mesalib/include/GL/gl.h
@@ -67,7 +67,7 @@
#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */
# define GLAPI extern
# define GLAPIENTRY __stdcall
-#elif defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+#elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define GLAPI __attribute__((visibility("default")))
# define GLAPIENTRY
#endif /* WIN32 && !CYGWIN */
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index b0d538de6..f5cc5cb3b 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -59,7 +59,6 @@ struct blitter_context_priv
float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
/* Templates for various state objects. */
- struct pipe_sampler_state template_sampler_state;
/* Constant state objects. */
/* Vertex shaders. */
@@ -92,8 +91,8 @@ struct blitter_context_priv
void *velem_uint_state;
void *velem_sint_state;
- /* Sampler state for clamping to a miplevel. */
- void *sampler_state[PIPE_MAX_TEXTURE_LEVELS * 2];
+ /* Sampler state. */
+ void *sampler_state;
/* Rasterizer state. */
void *rs_state;
@@ -126,7 +125,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
struct pipe_blend_state blend;
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state rs_state;
- struct pipe_sampler_state *sampler_state;
+ struct pipe_sampler_state sampler_state;
struct pipe_vertex_element velem[2];
unsigned i;
@@ -192,13 +191,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
/* sampler state */
- sampler_state = &ctx->template_sampler_state;
- sampler_state->wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler_state->wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler_state->wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler_state->normalized_coords = TRUE;
- /* The sampler state objects which sample from a specified mipmap level
- * are created on-demand. */
+ memset(&sampler_state, 0, sizeof(sampler_state));
+ sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state.normalized_coords = 1;
+ ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
/* rasterizer state */
memset(&rs_state, 0, sizeof(rs_state));
@@ -292,10 +290,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_fs_state(pipe, ctx->fs_col_int[i]);
}
- for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS * 2; i++)
- if (ctx->sampler_state[i])
- pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
-
+ pipe->delete_sampler_state(pipe, ctx->sampler_state);
pipe_resource_reference(&ctx->vbuf, NULL);
FREE(ctx);
}
@@ -497,21 +492,22 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx,
}
}
-static void get_texcoords(struct pipe_resource *src,
- unsigned level,
+static void get_texcoords(struct pipe_sampler_view *src,
+ unsigned src_width0, unsigned src_height0,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
- boolean normalized, float out[4])
+ float out[4])
{
- if(normalized)
- {
- out[0] = x1 / (float)u_minify(src->width0, level);
- out[1] = y1 / (float)u_minify(src->height0, level);
- out[2] = x2 / (float)u_minify(src->width0, level);
- out[3] = y2 / (float)u_minify(src->height0, level);
- }
- else
- {
+ struct pipe_resource *tex = src->texture;
+ unsigned level = src->u.tex.first_level;
+ boolean normalized = tex->target != PIPE_TEXTURE_RECT;
+
+ if (normalized) {
+ out[0] = x1 / (float)u_minify(src_width0, level);
+ out[1] = y1 / (float)u_minify(src_height0, level);
+ out[2] = x2 / (float)u_minify(src_width0, level);
+ out[3] = y2 / (float)u_minify(src_height0, level);
+ } else {
out[0] = x1;
out[1] = y1;
out[2] = x2;
@@ -535,76 +531,52 @@ static void set_texcoords_in_vertices(const float coord[4],
out[1] = coord[3]; /*t3.t*/
}
-static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level,
- unsigned x1, unsigned y1,
- unsigned x2, unsigned y2)
+static void blitter_set_texcoords(struct blitter_context_priv *ctx,
+ struct pipe_sampler_view *src,
+ unsigned src_width0, unsigned src_height0,
+ unsigned layer,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2)
{
unsigned i;
float coord[4];
+ float face_coord[4][2];
- get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
- set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
+ get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord);
- for (i = 0; i < 4; i++) {
- ctx->vertices[i][1][2] = 0; /*r*/
- ctx->vertices[i][1][3] = 1; /*q*/
+ if (src->texture->target == PIPE_TEXTURE_CUBE) {
+ set_texcoords_in_vertices(coord, &face_coord[0][0], 2);
+ util_map_texcoords2d_onto_cubemap(layer,
+ /* pointer, stride in floats */
+ &face_coord[0][0], 2,
+ &ctx->vertices[0][1][0], 8);
+ } else {
+ set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
}
-}
-
-static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level,
- unsigned zslice,
- unsigned x1, unsigned y1,
- unsigned x2, unsigned y2,
- boolean normalized)
-{
- int i;
- float r = normalized ? zslice / (float)u_minify(src->depth0, level) : zslice;
-
- blitter_set_texcoords_2d(ctx, src, level, x1, y1, x2, y2);
-
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][2] = r; /*r*/
-}
-static void blitter_set_texcoords_1d_array(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level,
- unsigned zslice,
- unsigned x1, unsigned x2)
-{
- int i;
- float r = zslice;
-
- blitter_set_texcoords_2d(ctx, src, level, x1, 0, x2, 0);
-
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][1] = r; /*r*/
-}
-
-static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level, unsigned face,
- unsigned x1, unsigned y1,
- unsigned x2, unsigned y2)
-{
- int i;
- float coord[4];
- float st[4][2];
+ /* Set the layer. */
+ switch (src->texture->target) {
+ case PIPE_TEXTURE_3D:
+ {
+ float r = layer / (float)u_minify(src->texture->depth0,
+ src->u.tex.first_level);
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][2] = r; /*r*/
+ }
+ break;
- get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
- set_texcoords_in_vertices(coord, &st[0][0], 2);
+ case PIPE_TEXTURE_1D_ARRAY:
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][1] = layer; /*t*/
+ break;
- util_map_texcoords2d_onto_cubemap(face,
- /* pointer, stride in floats */
- &st[0][0], 2,
- &ctx->vertices[0][1][0], 8);
+ case PIPE_TEXTURE_2D_ARRAY:
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][2] = layer; /*r*/
+ break;
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][3] = 1; /*q*/
+ default:;
+ }
}
static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
@@ -615,31 +587,6 @@ static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
}
static INLINE
-void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
- int miplevel, boolean normalized)
-{
- struct pipe_context *pipe = ctx->base.pipe;
- struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state;
-
- assert(miplevel < PIPE_MAX_TEXTURE_LEVELS);
-
- /* Create the sampler state on-demand. */
- if (!ctx->sampler_state[miplevel * 2 + normalized]) {
- sampler_state->lod_bias = miplevel;
- sampler_state->min_lod = miplevel;
- sampler_state->max_lod = miplevel;
- sampler_state->normalized_coords = normalized;
-
- ctx->sampler_state[miplevel * 2 + normalized] = pipe->create_sampler_state(pipe,
- sampler_state);
- }
-
- /* Return void** so that it can be passed to bind_fragment_sampler_states
- * directly. */
- return &ctx->sampler_state[miplevel * 2 + normalized];
-}
-
-static INLINE
void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs,
boolean int_format)
{
@@ -864,27 +811,16 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_surface *dstsurf, surf_templ;
- struct pipe_framebuffer_state fb_state;
struct pipe_sampler_view viewTempl, *view;
unsigned bind;
- unsigned width = srcbox->width;
- unsigned height = srcbox->height;
boolean is_stencil, is_depth;
- boolean normalized;
/* Give up if textures are not set. */
assert(dst && src);
if (!dst || !src)
return;
- /* Sanity checks. */
- if (dst == src) {
- assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
- dstx, dstx + width, dsty, dsty + height));
- }
assert(src->target < PIPE_MAX_TEXTURE_TYPES);
- /* XXX should handle 3d regions */
- assert(srcbox->depth == 1);
/* Is this a ZS format? */
is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
@@ -902,22 +838,60 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
dst->nr_samples, bind) ||
!screen->is_format_supported(screen, src->format, src->target,
src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
- ctx->base.running = TRUE;
+ blitter_set_running_flag(ctx);
util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
src, srclevel, srcbox);
- ctx->base.running = FALSE;
+ blitter_unset_running_flag(ctx);
return;
}
- /* Get surface. */
+ /* Initialize the surface. */
memset(&surf_templ, 0, sizeof(surf_templ));
u_surface_default_template(&surf_templ, dst, bind);
surf_templ.format = util_format_linear(dst->format);
surf_templ.u.tex.level = dstlevel;
surf_templ.u.tex.first_layer = dstz;
- surf_templ.u.tex.last_layer = dstz;
+ surf_templ.u.tex.last_layer = dstz + srcbox->depth - 1;
dstsurf = pipe->create_surface(pipe, dst, &surf_templ);
+ /* Initialize the sampler view. */
+ u_sampler_view_default_template(&viewTempl, src,
+ util_format_linear(src->format));
+ viewTempl.u.tex.first_level = srclevel;
+ viewTempl.u.tex.last_level = srclevel;
+ view = pipe->create_sampler_view(pipe, src, &viewTempl);
+
+ /* Copy. */
+ util_blitter_copy_texture_view(blitter, dstsurf, dstx, dsty, view, srcbox,
+ src->width0, src->height0);
+
+ pipe_surface_reference(&dstsurf, NULL);
+ pipe_sampler_view_reference(&view, NULL);
+}
+
+void util_blitter_copy_texture_view(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_sampler_view *src,
+ const struct pipe_box *srcbox,
+ unsigned src_width0, unsigned src_height0)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->base.pipe;
+ struct pipe_framebuffer_state fb_state;
+ enum pipe_texture_target src_target = src->texture->target;
+ unsigned width = srcbox->width;
+ unsigned height = srcbox->height;
+
+ /* Sanity checks. */
+ if (dst->texture == src->texture &&
+ dst->u.tex.level == src->u.tex.first_level) {
+ assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
+ dstx, dstx + width, dsty, dsty + height));
+ }
+ /* XXX should handle 3d regions */
+ assert(srcbox->depth == 1);
+
/* Check whether the states are properly saved. */
blitter_set_running_flag(ctx);
blitter_check_saved_vertex_states(ctx);
@@ -926,60 +900,55 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
blitter_check_saved_fb_state(ctx);
/* Initialize framebuffer state. */
- fb_state.width = dstsurf->width;
- fb_state.height = dstsurf->height;
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
- if (is_depth) {
+ if (util_format_is_depth_or_stencil(dst->format)) {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
pipe->bind_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_keep_stencil);
pipe->bind_fs_state(pipe,
- blitter_get_fs_texfetch_depth(ctx, src->target));
+ blitter_get_fs_texfetch_depth(ctx, src_target));
fb_state.nr_cbufs = 0;
- fb_state.zsbuf = dstsurf;
+ fb_state.zsbuf = dst;
} else {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_fs_state(pipe,
- blitter_get_fs_texfetch_col(ctx, src->target));
+ blitter_get_fs_texfetch_col(ctx, src_target));
fb_state.nr_cbufs = 1;
- fb_state.cbufs[0] = dstsurf;
+ fb_state.cbufs[0] = dst;
fb_state.zsbuf = 0;
}
- normalized = src->target != PIPE_TEXTURE_RECT;
-
- /* Initialize sampler view. */
- u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format));
- view = pipe->create_sampler_view(pipe, src, &viewTempl);
-
/* Set rasterizer state, shaders, and textures. */
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vs_state(pipe, ctx->vs);
if (ctx->has_geometry_shader)
pipe->bind_gs_state(pipe, NULL);
- pipe->bind_fragment_sampler_states(pipe, 1,
- blitter_get_sampler_state(ctx, srclevel, normalized));
+ pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
- pipe->set_fragment_sampler_views(pipe, 1, &view);
+ pipe->set_fragment_sampler_views(pipe, 1, &src);
pipe->set_framebuffer_state(pipe, &fb_state);
- blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
+ blitter_set_dst_dimensions(ctx, dst->width, dst->height);
- switch (src->target) {
+ switch (src_target) {
/* Draw the quad with the draw_rectangle callback. */
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_RECT:
{
/* Set texture coordinates. - use a pipe color union
- * for interface purposes
+ * for interface purposes.
+ * XXX pipe_color_union is a wrong name since we use that to set
+ * texture coordinates too.
*/
union pipe_color_union coord;
- get_texcoords(src, srclevel, srcbox->x, srcbox->y,
- srcbox->x+width, srcbox->y+height, normalized, coord.f);
+ get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
+ srcbox->x+width, srcbox->y+height, coord.f);
/* Draw. */
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
@@ -990,24 +959,14 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
/* Draw the quad with the generic codepath. */
default:
/* Set texture coordinates. */
- switch (src->target) {
+ switch (src_target) {
case PIPE_TEXTURE_1D_ARRAY:
- blitter_set_texcoords_1d_array(ctx, src, srclevel, srcbox->y,
- srcbox->x, srcbox->x + width);
- break;
-
case PIPE_TEXTURE_2D_ARRAY:
case PIPE_TEXTURE_3D:
- blitter_set_texcoords_3d(ctx, src, srclevel, srcbox->z,
- srcbox->x, srcbox->y,
- srcbox->x + width, srcbox->y + height,
- src->target == PIPE_TEXTURE_3D);
- break;
-
case PIPE_TEXTURE_CUBE:
- blitter_set_texcoords_cube(ctx, src, srclevel, srcbox->z,
- srcbox->x, srcbox->y,
- srcbox->x + width, srcbox->y + height);
+ blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z,
+ srcbox->y, srcbox->x,
+ srcbox->x + width, srcbox->y + height);
break;
default:
@@ -1028,9 +987,6 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
blitter_restore_textures(ctx);
blitter_restore_fb_state(ctx);
blitter_unset_running_flag(ctx);
-
- pipe_surface_reference(&dstsurf, NULL);
- pipe_sampler_view_reference(&view, NULL);
}
/* Clear a region of a color surface to a constant value. */
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h
index 798096e74..3e1457ae0 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.h
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h
@@ -190,6 +190,30 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
boolean ignore_stencil);
/**
+ * Same as util_blitter_copy_texture, but dst and src are pipe_surface and
+ * pipe_sampler_view, respectively. The mipmap level and dstz are part of
+ * the views.
+ *
+ * Drivers can use this to change resource properties (like format, width,
+ * height) by changing how the views interpret them, instead of changing
+ * pipe_resource directly. This is usually needed to accelerate copying of
+ * compressed formats.
+ *
+ * src_width0 and src_height0 are sampler_view-private properties that
+ * override pipe_resource. The blitter uses them for computation of texture
+ * coordinates. The dst dimensions are supplied through pipe_surface::width
+ * and height.
+ *
+ * NOTE: There are no checks whether the blit is actually supported.
+ */
+void util_blitter_copy_texture_view(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_sampler_view *src,
+ const struct pipe_box *srcbox,
+ unsigned src_width0, unsigned src_height0);
+
+/**
* Clear a region of a (color) surface to a constant value.
*
* These states must be saved in the blitter in addition to the state objects
diff --git a/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c b/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c
index 71fe53e3a..a2319d0c4 100644
--- a/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -131,8 +131,9 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
upload->bind,
PIPE_USAGE_STREAM,
size );
- if (upload->buffer == NULL)
- goto fail;
+ if (upload->buffer == NULL) {
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
/* Map the new buffer. */
upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
@@ -140,17 +141,16 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
PIPE_TRANSFER_WRITE |
PIPE_TRANSFER_FLUSH_EXPLICIT,
&upload->transfer);
-
+ if (upload->map == NULL) {
+ upload->size = 0;
+ pipe_resource_reference(&upload->buffer, NULL);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
+
upload->size = size;
upload->offset = 0;
- return 0;
-
-fail:
- if (upload->buffer)
- pipe_resource_reference( &upload->buffer, NULL );
-
- return PIPE_ERROR_OUT_OF_MEMORY;
+ return PIPE_OK;
}
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
@@ -170,7 +170,7 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
if (MAX2(upload->offset, alloc_offset) + alloc_size > upload->size) {
enum pipe_error ret = u_upload_alloc_buffer(upload,
alloc_offset + alloc_size);
- if (ret)
+ if (ret != PIPE_OK)
return ret;
*flushed = TRUE;
@@ -187,6 +187,11 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
PIPE_TRANSFER_FLUSH_EXPLICIT |
PIPE_TRANSFER_UNSYNCHRONIZED,
&upload->transfer);
+ if (!upload->map) {
+ pipe_resource_reference(outbuf, NULL);
+ *ptr = NULL;
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
}
assert(offset < upload->buffer->width0);
@@ -214,7 +219,7 @@ enum pipe_error u_upload_data( struct u_upload_mgr *upload,
enum pipe_error ret = u_upload_alloc(upload, min_out_offset, size,
out_offset, outbuf, flushed,
(void**)&ptr);
- if (ret)
+ if (ret != PIPE_OK)
return ret;
memcpy(ptr, data, size);
@@ -247,8 +252,7 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
&transfer);
if (map == NULL) {
- ret = PIPE_ERROR_OUT_OF_MEMORY;
- goto done;
+ return PIPE_ERROR_OUT_OF_MEMORY;
}
if (0)
@@ -261,9 +265,7 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
out_offset,
outbuf, flushed );
-done:
- if (map)
- pipe_buffer_unmap( upload->pipe, transfer );
+ pipe_buffer_unmap( upload->pipe, transfer );
return ret;
}
diff --git a/mesalib/src/glsl/Makefile b/mesalib/src/glsl/Makefile
index b2efb2abc..504f1fb43 100644
--- a/mesalib/src/glsl/Makefile
+++ b/mesalib/src/glsl/Makefile
@@ -53,6 +53,7 @@ CXX_SOURCES = \
ir_variable_refcount.cpp \
linker.cpp \
link_functions.cpp \
+ link_uniforms.cpp \
loop_analysis.cpp \
loop_controls.cpp \
loop_unroll.cpp \
diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript
index b4786c5e5..09c7edbc4 100644
--- a/mesalib/src/glsl/SConscript
+++ b/mesalib/src/glsl/SConscript
@@ -64,6 +64,7 @@ glsl_sources = [
'ir_variable_refcount.cpp',
'linker.cpp',
'link_functions.cpp',
+ 'link_uniforms.cpp',
'loop_analysis.cpp',
'loop_controls.cpp',
'loop_unroll.cpp',
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index a9075b2b1..e2112fe6d 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -883,8 +883,27 @@ ast_struct_specifier::ast_struct_specifier(char *identifier,
this->declarations.push_degenerate_list_at_head(&declarator_list->link);
}
+/**
+ * Do the set of common optimizations passes
+ *
+ * \param ir List of instructions to be optimized
+ * \param linked Is the shader linked? This enables
+ * optimizations passes that remove code at
+ * global scope and could cause linking to
+ * fail.
+ * \param uniform_locations_assigned Have locations already been assigned for
+ * uniforms? This prevents the declarations
+ * of unused uniforms from being removed.
+ * The setting of this flag only matters if
+ * \c linked is \c true.
+ * \param max_unroll_iterations Maximum number of loop iterations to be
+ * unrolled. Setting to 0 forces all loops
+ * to be unrolled.
+ */
bool
-do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
+do_common_optimization(exec_list *ir, bool linked,
+ bool uniform_locations_assigned,
+ unsigned max_unroll_iterations)
{
GLboolean progress = GL_FALSE;
@@ -900,7 +919,7 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration
progress = do_copy_propagation(ir) || progress;
progress = do_copy_propagation_elements(ir) || progress;
if (linked)
- progress = do_dead_code(ir) || progress;
+ progress = do_dead_code(ir, uniform_locations_assigned) || progress;
else
progress = do_dead_code_unlinked(ir) || progress;
progress = do_dead_code_local(ir) || progress;
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index b3fe6cf96..83f084d88 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -39,6 +39,25 @@
#include "ir_visitor.h"
#include "glsl_types.h"
+/* Using C99 rounding functions for roundToEven() implementation is
+ * difficult, because round(), rint, and nearbyint() are affected by
+ * fesetenv(), which the application may have done for its own
+ * purposes. Mesa's IROUND macro is close to what we want, but it
+ * rounds away from 0 on n + 0.5.
+ */
+static int
+round_to_even(float val)
+{
+ int rounded = IROUND(val);
+
+ if (val - floor(val) == 0.5) {
+ if (rounded % 2 != 0)
+ rounded += val > 0 ? -1 : 1;
+ }
+
+ return rounded;
+}
+
static float
dot(ir_constant *op0, ir_constant *op1)
{
@@ -196,6 +215,13 @@ ir_expression::constant_expression_value()
}
break;
+ case ir_unop_round_even:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = round_to_even(op[0]->value.f[c]);
+ }
+ break;
+
case ir_unop_ceil:
assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
@@ -1324,6 +1350,9 @@ ir_call::constant_expression_value()
* op[1]->value.f[c];
}
}
+ } else if (strcmp(callee, "round") == 0 ||
+ strcmp(callee, "roundEven") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_round_even, op[0]);
} else if (strcmp(callee, "sign") == 0) {
expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
} else if (strcmp(callee, "sin") == 0) {
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index af80e26b9..7b32e84f0 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -37,7 +37,9 @@
#define MOD_TO_FRACT 0x20
#define INT_DIV_TO_MUL_RCP 0x40
-bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations);
+bool do_common_optimization(exec_list *ir, bool linked,
+ bool uniform_locations_assigned,
+ unsigned max_unroll_iterations);
bool do_algebraic(exec_list *instructions);
bool do_constant_folding(exec_list *instructions);
@@ -46,7 +48,7 @@ bool do_constant_variable_unlinked(exec_list *instructions);
bool do_copy_propagation(exec_list *instructions);
bool do_copy_propagation_elements(exec_list *instructions);
bool do_constant_propagation(exec_list *instructions);
-bool do_dead_code(exec_list *instructions);
+bool do_dead_code(exec_list *instructions, bool uniform_locations_assigned);
bool do_dead_code_local(exec_list *instructions);
bool do_dead_code_unlinked(exec_list *instructions);
bool do_dead_functions(exec_list *instructions);
diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp
index 6ae3b1f9e..8337e15b8 100644
--- a/mesalib/src/glsl/ir_variable.cpp
+++ b/mesalib/src/glsl/ir_variable.cpp
@@ -232,11 +232,11 @@ MATRIX(gl_TextureMatrixInverseTranspose,
static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
};
#undef MATRIX
@@ -615,6 +615,8 @@ generate_130_uniforms(exec_list *instructions,
add_builtin_constant(instructions, symtab, "gl_MaxClipDistances",
state->Const.MaxClipPlanes);
+ add_builtin_constant(instructions, symtab, "gl_MaxVaryingComponents",
+ state->Const.MaxVaryingFloats);
}
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
new file mode 100644
index 000000000..6dd1f5354
--- /dev/null
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2011 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/core.h"
+#include "ir.h"
+#include "linker.h"
+#include "glsl_symbol_table.h"
+#include "program/hash_table.h"
+
+/**
+ * \file link_uniforms.cpp
+ * Assign locations for GLSL uniforms.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+void
+uniform_field_visitor::process(ir_variable *var)
+{
+ const glsl_type *t = var->type;
+
+ /* Only strdup the name if we actually will need to modify it. */
+ if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
+ char *name = ralloc_strdup(NULL, var->name);
+ recursion(var->type, &name, strlen(name));
+ ralloc_free(name);
+ } else {
+ this->visit_field(t, var->name);
+ }
+}
+
+void
+uniform_field_visitor::recursion(const glsl_type *t, char **name,
+ unsigned name_length)
+{
+ /* Records need to have each field processed individually.
+ *
+ * Arrays of records need to have each array element processed
+ * individually, then each field of the resulting array elements processed
+ * individually.
+ */
+ if (t->is_record()) {
+ for (unsigned i = 0; i < t->length; i++) {
+ const char *field = t->fields.structure[i].name;
+
+ /* Append '.field' to the current uniform name. */
+ ralloc_asprintf_rewrite_tail(name, name_length, ".%s", field);
+
+ recursion(t->fields.structure[i].type, name,
+ name_length + 1 + strlen(field));
+ }
+ } else if (t->is_array() && t->fields.array->is_record()) {
+ for (unsigned i = 0; i < t->length; i++) {
+ char subscript[13];
+
+ /* Append the subscript to the current uniform name */
+ const unsigned subscript_length = snprintf(subscript, 13, "[%u]", i);
+ ralloc_asprintf_rewrite_tail(name, name_length, "%s", subscript);
+
+ recursion(t->fields.array, name, name_length + subscript_length);
+ }
+ } else {
+ this->visit_field(t, *name);
+ }
+}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index a7c38a342..beadec6f6 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -1742,14 +1742,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (ctx->ShaderCompilerOptions[i].LowerClipDistance)
lower_clip_distance(prog->_LinkedShaders[i]->ir);
- while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
+ while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, false, 32))
;
}
- update_array_sizes(prog);
-
- assign_uniform_locations(prog);
-
/* FINISHME: The value of the max_attribute_index parameter is
* FINISHME: implementation dependent based on the value of
* FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
@@ -1785,6 +1781,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX],
ir_var_out);
+
+ /* Eliminate code that is now dead due to unused vertex outputs being
+ * demoted.
+ */
+ while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir, false))
+ ;
}
if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
@@ -1793,14 +1795,30 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
demote_shader_inputs_and_outputs(sh, ir_var_in);
demote_shader_inputs_and_outputs(sh, ir_var_inout);
demote_shader_inputs_and_outputs(sh, ir_var_out);
+
+ /* Eliminate code that is now dead due to unused geometry outputs being
+ * demoted.
+ */
+ while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir, false))
+ ;
}
if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
demote_shader_inputs_and_outputs(sh, ir_var_in);
+
+ /* Eliminate code that is now dead due to unused fragment inputs being
+ * demoted. This shouldn't actually do anything other than remove
+ * declarations of the (now unused) global variables.
+ */
+ while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir, false))
+ ;
}
+ update_array_sizes(prog);
+ assign_uniform_locations(prog);
+
/* OpenGL ES requires that a vertex shader and a fragment shader both be
* present in a linked program. By checking for use of shading language
* version 1.00, we also catch the GL_ARB_ES2_compatibility case.
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 769cf68b6..78c632961 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -1,3 +1,4 @@
+/* -*- c++ -*- */
/*
* Copyright © 2010 Intel Corporation
*
@@ -29,4 +30,46 @@ extern bool
link_function_calls(gl_shader_program *prog, gl_shader *main,
gl_shader **shader_list, unsigned num_shaders);
+/**
+ * Class for processing all of the leaf fields of an uniform
+ *
+ * Leaves are, roughly speaking, the parts of the uniform that the application
+ * could query with \c glGetUniformLocation (or that could be returned by
+ * \c glGetActiveUniforms).
+ *
+ * Classes my derive from this class to implement specific functionality.
+ * This class only provides the mechanism to iterate over the leaves. Derived
+ * classes must implement \c ::visit_field and may override \c ::process.
+ */
+class uniform_field_visitor {
+public:
+ /**
+ * Begin processing a uniform
+ *
+ * Classes that overload this function should call \c ::process from the
+ * base class to start the recursive processing of the uniform.
+ *
+ * \param var The uniform variable that is to be processed
+ *
+ * Calls \c ::visit_field for each leaf of the uniform.
+ */
+ void process(ir_variable *var);
+
+protected:
+ /**
+ * Method invoked for each leaf of the uniform
+ *
+ * \param type Type of the field.
+ * \param name Fully qualified name of the field.
+ */
+ virtual void visit_field(const glsl_type *type, const char *name) = 0;
+
+private:
+ /**
+ * \param name_length Length of the current name \b not including the
+ * terminating \c NUL character.
+ */
+ void recursion(const glsl_type *t, char **name, unsigned name_length);
+};
+
#endif /* GLSL_LINKER_H */
diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
index 7b89a1539..2c5d5612d 100644
--- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp
+++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
@@ -79,6 +79,9 @@ public:
bool
lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth)
{
+ if (max_depth == UINT_MAX)
+ return false;
+
ir_if_to_cond_assign_visitor v(max_depth);
visit_list_elements(&v, instructions);
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp
index 019213750..e17422471 100644
--- a/mesalib/src/glsl/main.cpp
+++ b/mesalib/src/glsl/main.cpp
@@ -166,7 +166,7 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader)
if (!state->error && !shader->ir->is_empty()) {
bool progress;
do {
- progress = do_common_optimization(shader->ir, false, 32);
+ progress = do_common_optimization(shader->ir, false, false, 32);
} while (progress);
validate_ir_tree(shader->ir);
diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp
index cb500d2d1..5b9546ad4 100644
--- a/mesalib/src/glsl/opt_dead_code.cpp
+++ b/mesalib/src/glsl/opt_dead_code.cpp
@@ -42,7 +42,7 @@ static bool debug = false;
* for usage on an unlinked instruction stream.
*/
bool
-do_dead_code(exec_list *instructions)
+do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
{
ir_variable_refcount_visitor v;
bool progress = false;
@@ -94,10 +94,11 @@ do_dead_code(exec_list *instructions)
*/
/* uniform initializers are precious, and could get used by another
- * stage.
+ * stage. Also, once uniform locations have been assigned, the
+ * declaration cannot be deleted.
*/
if (entry->var->mode == ir_var_uniform &&
- entry->var->constant_value)
+ (uniform_locations_assigned || entry->var->constant_value))
continue;
entry->var->remove();
@@ -132,7 +133,12 @@ do_dead_code_unlinked(exec_list *instructions)
foreach_iter(exec_list_iterator, sigiter, *f) {
ir_function_signature *sig =
(ir_function_signature *) sigiter.get();
- if (do_dead_code(&sig->body))
+ /* The setting of the uniform_locations_assigned flag here is
+ * irrelevent. If there is a uniform declaration encountered
+ * inside the body of the function, something has already gone
+ * terribly, terribly wrong.
+ */
+ if (do_dead_code(&sig->body, false))
progress = true;
}
}
diff --git a/mesalib/src/glsl/ralloc.c b/mesalib/src/glsl/ralloc.c
index fb48a91c5..f5f3934ac 100644
--- a/mesalib/src/glsl/ralloc.c
+++ b/mesalib/src/glsl/ralloc.c
@@ -439,7 +439,28 @@ ralloc_asprintf_append(char **str, const char *fmt, ...)
bool
ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
{
- size_t existing_length, new_length;
+ size_t existing_length;
+ assert(str != NULL);
+ existing_length = *str ? strlen(*str) : 0;
+ return ralloc_vasprintf_rewrite_tail(str, existing_length, fmt, args);
+}
+
+bool
+ralloc_asprintf_rewrite_tail(char **str, size_t start, const char *fmt, ...)
+{
+ bool success;
+ va_list args;
+ va_start(args, fmt);
+ success = ralloc_vasprintf_rewrite_tail(str, start, fmt, args);
+ va_end(args);
+ return success;
+}
+
+bool
+ralloc_vasprintf_rewrite_tail(char **str, size_t start, const char *fmt,
+ va_list args)
+{
+ size_t new_length;
char *ptr;
assert(str != NULL);
@@ -450,14 +471,13 @@ ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
return true;
}
- existing_length = strlen(*str);
new_length = printf_length(fmt, args);
- ptr = resize(*str, existing_length + new_length + 1);
+ ptr = resize(*str, start + new_length + 1);
if (unlikely(ptr == NULL))
return false;
- vsnprintf(ptr + existing_length, new_length + 1, fmt, args);
+ vsnprintf(ptr + start, new_length + 1, fmt, args);
*str = ptr;
return true;
}
diff --git a/mesalib/src/glsl/ralloc.h b/mesalib/src/glsl/ralloc.h
index d5338152f..1324f3466 100644
--- a/mesalib/src/glsl/ralloc.h
+++ b/mesalib/src/glsl/ralloc.h
@@ -314,9 +314,60 @@ char *ralloc_asprintf (const void *ctx, const char *fmt, ...);
char *ralloc_vasprintf(const void *ctx, const char *fmt, va_list args);
/**
+ * Rewrite the tail of an existing string, starting at a given index.
+ *
+ * Overwrites the contents of *str starting at \p start with newly formatted
+ * text, including a new null-terminator. Allocates more memory as necessary.
+ *
+ * This can be used to append formatted text when the length of the existing
+ * string is already known, saving a strlen() call.
+ *
+ * \sa ralloc_asprintf_append
+ *
+ * \param str The string to be updated.
+ * \param start The index to start appending new data at.
+ * \param fmt A printf-style formatting string
+ *
+ * \p str will be updated to the new pointer unless allocation fails.
+ *
+ * \return True unless allocation failed.
+ */
+bool ralloc_asprintf_rewrite_tail(char **str, size_t start,
+ const char *fmt, ...);
+
+/**
+ * Rewrite the tail of an existing string, starting at a given index.
+ *
+ * Overwrites the contents of *str starting at \p start with newly formatted
+ * text, including a new null-terminator. Allocates more memory as necessary.
+ *
+ * This can be used to append formatted text when the length of the existing
+ * string is already known, saving a strlen() call.
+ *
+ * \sa ralloc_vasprintf_append
+ *
+ * \param str The string to be updated.
+ * \param start The index to start appending new data at.
+ * \param fmt A printf-style formatting string
+ * \param args A va_list containing the data to be formatted
+ *
+ * \p str will be updated to the new pointer unless allocation fails.
+ *
+ * \return True unless allocation failed.
+ */
+bool ralloc_vasprintf_rewrite_tail(char **str, size_t start, const char *fmt,
+ va_list args);
+
+/**
* Append formatted text to the supplied string.
*
+ * This is equivalent to
+ * \code
+ * ralloc_asprintf_rewrite_tail(str, strlen(*str), fmt, ...)
+ * \endcode
+ *
* \sa ralloc_asprintf
+ * \sa ralloc_asprintf_rewrite_tail
* \sa ralloc_strcat
*
* \p str will be updated to the new pointer unless allocation fails.
@@ -328,7 +379,13 @@ bool ralloc_asprintf_append (char **str, const char *fmt, ...);
/**
* Append formatted text to the supplied string, given a va_list.
*
+ * This is equivalent to
+ * \code
+ * ralloc_vasprintf_rewrite_tail(str, strlen(*str), fmt, args)
+ * \endcode
+ *
* \sa ralloc_vasprintf
+ * \sa ralloc_vasprintf_rewrite_tail
* \sa ralloc_strcat
*
* \p str will be updated to the new pointer unless allocation fails.
diff --git a/mesalib/src/glsl/test_optpass.cpp b/mesalib/src/glsl/test_optpass.cpp
index 89b7f8338..6abafb5d3 100644
--- a/mesalib/src/glsl/test_optpass.cpp
+++ b/mesalib/src/glsl/test_optpass.cpp
@@ -64,7 +64,7 @@ do_optimization(struct exec_list *ir, const char *optimization)
if (sscanf(optimization, "do_common_optimization ( %d , %d ) ",
&int_0, &int_1) == 2) {
- return do_common_optimization(ir, int_0 != 0, int_1);
+ return do_common_optimization(ir, int_0 != 0, false, int_1);
} else if (strcmp(optimization, "do_algebraic") == 0) {
return do_algebraic(ir);
} else if (strcmp(optimization, "do_constant_folding") == 0) {
@@ -80,7 +80,7 @@ do_optimization(struct exec_list *ir, const char *optimization)
} else if (strcmp(optimization, "do_constant_propagation") == 0) {
return do_constant_propagation(ir);
} else if (strcmp(optimization, "do_dead_code") == 0) {
- return do_dead_code(ir);
+ return do_dead_code(ir, false);
} else if (strcmp(optimization, "do_dead_code_local") == 0) {
return do_dead_code_local(ir);
} else if (strcmp(optimization, "do_dead_code_unlinked") == 0) {
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index d2c74b91d..75d25253e 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -52,6 +52,7 @@
#include "main/texstate.h"
#include "swrast_priv.h"
+#include "swrast/s_context.h"
/**
@@ -67,6 +68,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ struct swrast_texture_image *swImage;
uint32_t internalFormat;
gl_format texFormat;
@@ -77,6 +79,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
+ swImage = swrast_texture_image(texImage);
_mesa_lock_texture(&dri_ctx->Base, texObj);
@@ -90,7 +93,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
_mesa_init_teximage_fields(&dri_ctx->Base, target, texImage,
w, h, 1, 0, internalFormat, texFormat);
- sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)texImage->Data,
+ sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)swImage->Data,
dPriv->loaderPrivate);
_mesa_unlock_texture(&dri_ctx->Base, texObj);
diff --git a/mesalib/src/mesa/main/APIspec.xml b/mesalib/src/mesa/main/APIspec.xml
index 574480e28..a92bb437c 100644
--- a/mesalib/src/mesa/main/APIspec.xml
+++ b/mesalib/src/mesa/main/APIspec.xml
@@ -631,12 +631,6 @@
<desc name="pname">
<value name="GL_RGB_SCALE"/>
<value name="GL_ALPHA_SCALE"/>
-
- <desc name="param" convert="true" error="GL_INVALID_VALUE">
- <value name="1.0"/>
- <value name="2.0"/>
- <value name="4.0"/>
- </desc>
</desc>
<desc name="pname">
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index e67957d4d..1dc1c1b97 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -1279,30 +1279,6 @@ _mesa_PopAttrib(void)
/**
- * Helper for incrementing/decrementing vertex buffer object reference
- * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group.
- */
-static void
-adjust_buffer_object_ref_counts(struct gl_array_object *arrayObj, GLint step)
-{
- GLuint i;
-
- arrayObj->Vertex.BufferObj->RefCount += step;
- arrayObj->Weight.BufferObj->RefCount += step;
- arrayObj->Normal.BufferObj->RefCount += step;
- arrayObj->Color.BufferObj->RefCount += step;
- arrayObj->SecondaryColor.BufferObj->RefCount += step;
- arrayObj->FogCoord.BufferObj->RefCount += step;
- arrayObj->Index.BufferObj->RefCount += step;
- arrayObj->EdgeFlag.BufferObj->RefCount += step;
- for (i = 0; i < Elements(arrayObj->TexCoord); i++)
- arrayObj->TexCoord[i].BufferObj->RefCount += step;
- for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
- arrayObj->VertexAttrib[i].BufferObj->RefCount += step;
-}
-
-
-/**
* Copy gl_pixelstore_attrib from src to dst, updating buffer
* object refcounts.
*/
@@ -1327,6 +1303,151 @@ copy_pixelstore(struct gl_context *ctx,
#define GL_CLIENT_PACK_BIT (1<<20)
#define GL_CLIENT_UNPACK_BIT (1<<21)
+/**
+ * Copy gl_array_object from src to dest.
+ * 'dest' must be in an initialized state.
+ */
+static void
+copy_array_object(struct gl_context *ctx,
+ struct gl_array_object *dest,
+ struct gl_array_object *src)
+{
+ GLuint i;
+
+ /* skip Name */
+ /* skip RefCount */
+
+ /* In theory must be the same anyway, but on recreate make sure it matches */
+ dest->VBOonly = src->VBOonly;
+
+ _mesa_copy_client_array(ctx, &dest->Vertex, &src->Vertex);
+ _mesa_copy_client_array(ctx, &dest->Weight, &src->Weight);
+ _mesa_copy_client_array(ctx, &dest->Normal, &src->Normal);
+ _mesa_copy_client_array(ctx, &dest->Color, &src->Color);
+ _mesa_copy_client_array(ctx, &dest->SecondaryColor, &src->SecondaryColor);
+ _mesa_copy_client_array(ctx, &dest->FogCoord, &src->FogCoord);
+ _mesa_copy_client_array(ctx, &dest->Index, &src->Index);
+ _mesa_copy_client_array(ctx, &dest->EdgeFlag, &src->EdgeFlag);
+#if FEATURE_point_size_array
+ _mesa_copy_client_array(ctx, &dest->PointSize, &src->PointSize);
+#endif
+ for (i = 0; i < Elements(src->TexCoord); i++)
+ _mesa_copy_client_array(ctx, &dest->TexCoord[i], &src->TexCoord[i]);
+ for (i = 0; i < Elements(src->VertexAttrib); i++)
+ _mesa_copy_client_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
+
+ /* _Enabled must be the same than on push */
+ dest->_Enabled = src->_Enabled;
+ dest->_MaxElement = src->_MaxElement;
+}
+
+/**
+ * Copy gl_array_attrib from src to dest.
+ * 'dest' must be in an initialized state.
+ */
+static void
+copy_array_attrib(struct gl_context *ctx,
+ struct gl_array_attrib *dest,
+ struct gl_array_attrib *src)
+{
+ /* skip ArrayObj */
+ /* skip DefaultArrayObj, Objects */
+ dest->ActiveTexture = src->ActiveTexture;
+ dest->LockFirst = src->LockFirst;
+ dest->LockCount = src->LockCount;
+ dest->PrimitiveRestart = src->PrimitiveRestart;
+ dest->RestartIndex = src->RestartIndex;
+ /* skip NewState */
+ /* skip RebindArrays */
+
+ copy_array_object(ctx, dest->ArrayObj, src->ArrayObj);
+
+ /* skip ArrayBufferObj */
+ /* skip ElementArrayBufferObj */
+}
+
+/**
+ * Save the content of src to dest.
+ */
+static void
+save_array_attrib(struct gl_context *ctx,
+ struct gl_array_attrib *dest,
+ struct gl_array_attrib *src)
+{
+ /* Set the Name, needed for restore, but do never overwrite.
+ * Needs to match value in the object hash. */
+ dest->ArrayObj->Name = src->ArrayObj->Name;
+ /* And copy all of the rest. */
+ copy_array_attrib(ctx, dest, src);
+
+ /* Just reference them here */
+ _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
+ src->ArrayBufferObj);
+ _mesa_reference_buffer_object(ctx, &dest->ElementArrayBufferObj,
+ src->ElementArrayBufferObj);
+}
+
+/**
+ * Restore the content of src to dest.
+ */
+static void
+restore_array_attrib(struct gl_context *ctx,
+ struct gl_array_attrib *dest,
+ struct gl_array_attrib *src)
+{
+ /* Restore or recreate the array object by its name ... */
+ _mesa_BindVertexArrayAPPLE(src->ArrayObj->Name);
+
+ /* ... and restore its content */
+ copy_array_attrib(ctx, dest, src);
+
+ /* Restore or recreate the buffer objects by the names ... */
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
+ src->ArrayBufferObj->Name);
+ _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ src->ElementArrayBufferObj->Name);
+
+ /* Better safe than sorry?! */
+ dest->RebindArrays = GL_TRUE;
+
+ /* FIXME: Should some bits in ctx->Array->NewState also be set
+ * FIXME: here? It seems like it should be set to inclusive-or
+ * FIXME: of the old ArrayObj->_Enabled and the new _Enabled.
+ * ... just do it.
+ */
+ dest->NewState |= src->ArrayObj->_Enabled | dest->ArrayObj->_Enabled;
+}
+
+/**
+ * init/alloc the fields of 'attrib'.
+ * Needs to the init part matching free_array_attrib_data below.
+ */
+static void
+init_array_attrib_data(struct gl_context *ctx,
+ struct gl_array_attrib *attrib)
+{
+ /* Get a non driver gl_array_object. */
+ attrib->ArrayObj = CALLOC_STRUCT( gl_array_object );
+ _mesa_initialize_array_object(ctx, attrib->ArrayObj, 0);
+}
+
+/**
+ * Free/unreference the fields of 'attrib' but don't delete it (that's
+ * done later in the calling code).
+ * Needs to the cleanup part matching init_array_attrib_data above.
+ */
+static void
+free_array_attrib_data(struct gl_context *ctx,
+ struct gl_array_attrib *attrib)
+{
+ /* We use a non driver array object, so don't just unref since we would
+ * end up using the drivers DeleteArrayObject function for deletion. */
+ _mesa_delete_array_object(ctx, attrib->ArrayObj);
+ attrib->ArrayObj = 0;
+ _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &attrib->ElementArrayBufferObj, NULL);
+}
+
void GLAPIENTRY
_mesa_PushClientAttrib(GLbitfield mask)
@@ -1360,26 +1481,10 @@ _mesa_PushClientAttrib(GLbitfield mask)
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
struct gl_array_attrib *attr;
- struct gl_array_object *obj;
-
- attr = MALLOC_STRUCT( gl_array_attrib );
- obj = MALLOC_STRUCT( gl_array_object );
-
-#if FEATURE_ARB_vertex_buffer_object
- /* increment ref counts since we're copying pointers to these objects */
- ctx->Array.ArrayBufferObj->RefCount++;
- ctx->Array.ElementArrayBufferObj->RefCount++;
-#endif
-
- memcpy( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
- memcpy( obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object) );
-
- attr->ArrayObj = obj;
-
+ attr = CALLOC_STRUCT( gl_array_attrib );
+ init_array_attrib_data(ctx, attr);
+ save_array_attrib(ctx, attr, &ctx->Array);
save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr);
-
- /* bump reference counts on buffer objects */
- adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1);
}
ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
@@ -1426,36 +1531,10 @@ _mesa_PopClientAttrib(void)
ctx->NewState |= _NEW_PACKUNPACK;
break;
case GL_CLIENT_VERTEX_ARRAY_BIT: {
- struct gl_array_attrib * data =
+ struct gl_array_attrib * attr =
(struct gl_array_attrib *) node->data;
-
- adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, -1);
-
- ctx->Array.ActiveTexture = data->ActiveTexture;
- if (data->LockCount != 0)
- _mesa_LockArraysEXT(data->LockFirst, data->LockCount);
- else if (ctx->Array.LockCount)
- _mesa_UnlockArraysEXT();
-
- _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name );
-
-#if FEATURE_ARB_vertex_buffer_object
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
- data->ArrayBufferObj->Name);
- _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
- data->ElementArrayBufferObj->Name);
-#endif
-
- memcpy( ctx->Array.ArrayObj, data->ArrayObj,
- sizeof( struct gl_array_object ) );
-
- FREE( data->ArrayObj );
-
- /* FIXME: Should some bits in ctx->Array->NewState also be set
- * FIXME: here? It seems like it should be set to inclusive-or
- * FIXME: of the old ArrayObj->_Enabled and the new _Enabled.
- */
-
+ restore_array_attrib(ctx, &ctx->Array, attr);
+ free_array_attrib_data(ctx, attr);
ctx->NewState |= _NEW_ARRAY;
break;
}
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 431eafd38..4c77397d9 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -571,7 +571,7 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer)
/* Get pointer to old buffer object (to be unbound) */
oldBufObj = *bindTarget;
- if (oldBufObj && oldBufObj->Name == buffer)
+ if (oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending)
return; /* rebinding the same buffer object- no change */
/*
@@ -773,6 +773,17 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
/* The ID is immediately freed for re-use */
_mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]);
+ /* Make sure we do not run into the classic ABA problem on bind.
+ * We don't want to allow re-binding a buffer object that's been
+ * "deleted" by glDeleteBuffers().
+ *
+ * The explicit rebinding to the default object in the current context
+ * prevents the above in the current context, but another context
+ * sharing the same objects might suffer from this problem.
+ * The alternative would be to do the hash lookup in any case on bind
+ * which would introduce more runtime overhead than this.
+ */
+ bufObj->DeletePending = GL_TRUE;
_mesa_reference_buffer_object(ctx, &bufObj, NULL);
}
}
diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h
index 89d6cda91..921e30222 100644
--- a/mesalib/src/mesa/main/compiler.h
+++ b/mesalib/src/mesa/main/compiler.h
@@ -150,7 +150,7 @@ extern "C" {
* inline a static function that we later use in an alias. - ajax
*/
#ifndef PUBLIC
-# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# if (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define PUBLIC __attribute__((visibility("default")))
# define USED __attribute__((used))
# else
diff --git a/mesalib/src/mesa/main/context.h b/mesalib/src/mesa/main/context.h
index a4c7ba2c5..a9df0a866 100644
--- a/mesalib/src/mesa/main/context.h
+++ b/mesalib/src/mesa/main/context.h
@@ -233,7 +233,7 @@ do { \
* glBegin()/glEnd() pair, with return value.
*
* \param ctx GL context.
- * \param retval value to return value in case the assertion fails.
+ * \param retval value to return in case the assertion fails.
*/
#define ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval) \
do { \
@@ -274,7 +274,7 @@ do { \
* glBegin()/glEnd() pair and flush the vertices, with return value.
*
* \param ctx GL context.
- * \param retval value to return value in case the assertion fails.
+ * \param retval value to return in case the assertion fails.
*/
#define ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval) \
do { \
diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c
index 625649e9d..d901bddf8 100644
--- a/mesalib/src/mesa/main/dlist.c
+++ b/mesalib/src/mesa/main/dlist.c
@@ -939,7 +939,9 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
}
return image;
}
+
/* bad access! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access");
return NULL;
}
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index f9da54e73..c56062ac6 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -2486,6 +2486,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
void GLAPIENTRY
_mesa_GenerateMipmapEXT(GLenum target)
{
+ struct gl_texture_image *srcImage;
struct gl_texture_object *texObj;
GLboolean error;
@@ -2532,6 +2533,13 @@ _mesa_GenerateMipmapEXT(GLenum target)
}
_mesa_lock_texture(ctx, texObj);
+
+ srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
+ if (!srcImage) {
+ _mesa_unlock_texture(ctx, texObj);
+ return;
+ }
+
if (target == GL_TEXTURE_CUBE_MAP) {
GLuint face;
for (face = 0; face < 6; face++)
diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp
index 160a97c0c..3e449b03e 100644
--- a/mesalib/src/mesa/main/ff_fragment_shader.cpp
+++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp
@@ -1464,7 +1464,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
validate_ir_tree(p.shader->ir);
- while (do_common_optimization(p.shader->ir, false, 32))
+ while (do_common_optimization(p.shader->ir, false, false, 32))
;
reparent_ir(p.shader->ir, p.shader->ir);
diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c
index 345a1c53e..2469e4265 100644
--- a/mesalib/src/mesa/main/imports.c
+++ b/mesalib/src/mesa/main/imports.c
@@ -514,7 +514,7 @@ _mesa_ffsll(int64_t val)
#endif
#if !defined(__GNUC__) ||\
- ((_GNUC__ == 3 && __GNUC_MINOR__ < 4) && __GNUC__ < 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
/**
* Return number of bits set in given GLuint.
*/
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h
index 20fa148fe..797f35742 100644
--- a/mesalib/src/mesa/main/imports.h
+++ b/mesalib/src/mesa/main/imports.h
@@ -453,7 +453,7 @@ static inline int32_t
_mesa_next_pow_two_32(uint32_t x)
{
#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
uint32_t y = (x != 1);
return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
#else
@@ -472,7 +472,7 @@ static inline int64_t
_mesa_next_pow_two_64(uint64_t x)
{
#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
uint64_t y = (x != 1);
if (sizeof(x) == sizeof(long))
return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
@@ -499,7 +499,7 @@ static inline GLuint
_mesa_logbase2(GLuint n)
{
#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
return (31 - __builtin_clz(n | 1));
#else
GLuint pos = 0;
@@ -576,7 +576,7 @@ _mesa_init_sqrt_table(void);
#define _mesa_ffs(i) ffs(i)
#define _mesa_ffsll(i) ffsll(i)
-#if ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+#if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
#define _mesa_bitcount(i) __builtin_popcount(i)
#define _mesa_bitcount_64(i) __builtin_popcountll(i)
#else
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 17c645a7e..719dff3af 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1261,11 +1261,6 @@ struct gl_texture_image
GLuint Level; /**< Which mipmap level am I? */
/** Cube map face: index into gl_texture_object::Image[] array */
GLuint Face;
-
- GLuint RowStride; /**< Padded width in units of texels */
- GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
- each 2D slice in 'Data', in texels */
- GLvoid *Data; /**< Image data, accessed via FetchTexel() */
};
@@ -1535,6 +1530,7 @@ struct gl_buffer_object
GLintptr Offset; /**< Mapped offset */
GLsizeiptr Length; /**< Mapped length */
/*@}*/
+ GLboolean DeletePending; /**< true if buffer object is removed from the hash */
GLboolean Written; /**< Ever written to? (for debugging) */
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
};
diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c
index 092e541c5..ecdeaf5dc 100644
--- a/mesalib/src/mesa/main/pack.c
+++ b/mesalib/src/mesa/main/pack.c
@@ -3717,6 +3717,7 @@ _mesa_unpack_color_span_ubyte(struct gl_context *ctx,
if (!indexes) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+ free(rgba);
return;
}
diff --git a/mesalib/src/mesa/main/pixelstore.c b/mesalib/src/mesa/main/pixelstore.c
index d957950ed..81474491d 100644
--- a/mesalib/src/mesa/main/pixelstore.c
+++ b/mesalib/src/mesa/main/pixelstore.c
@@ -214,7 +214,7 @@ _mesa_PixelStorei( GLenum pname, GLint param )
void GLAPIENTRY
_mesa_PixelStoref( GLenum pname, GLfloat param )
{
- _mesa_PixelStorei( pname, (GLint) param );
+ _mesa_PixelStorei( pname, IROUND(param) );
}
diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c
index 98ca733c0..80fd03b91 100644
--- a/mesalib/src/mesa/main/state.c
+++ b/mesalib/src/mesa/main/state.c
@@ -461,7 +461,7 @@ static void
update_twoside(struct gl_context *ctx)
{
if (ctx->Shader.CurrentVertexProgram ||
- ctx->VertexProgram.Current) {
+ ctx->VertexProgram._Enabled) {
ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled;
} else {
ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled &&
diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c
index 03e05d5ef..0458b9b68 100644
--- a/mesalib/src/mesa/main/texcompress.c
+++ b/mesalib/src/mesa/main/texcompress.c
@@ -461,8 +461,8 @@ _mesa_decompress_image(gl_format format, GLuint width, GLuint height,
/* setup dummy texture image info */
memset(&texImage, 0, sizeof(texImage));
- texImage.Base.Data = (void *) src;
- texImage.Base.RowStride = srcRowStride;
+ texImage.Data = (void *) src;
+ texImage.RowStride = srcRowStride;
switch (format) {
/* DXT formats */
diff --git a/mesalib/src/mesa/main/texcompress_fxt1.c b/mesalib/src/mesa/main/texcompress_fxt1.c
index 41630a47c..d5c73e3b4 100644
--- a/mesalib/src/mesa/main/texcompress_fxt1.c
+++ b/mesalib/src/mesa/main/texcompress_fxt1.c
@@ -177,7 +177,7 @@ _mesa_fetch_texel_2d_f_rgba_fxt1( const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
(void) k;
- fxt1_decode_1(texImage->Base.Data, texImage->Base.RowStride, i, j, rgba);
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);
texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]);
texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]);
texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]);
@@ -192,7 +192,7 @@ _mesa_fetch_texel_2d_f_rgb_fxt1( const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
(void) k;
- fxt1_decode_1(texImage->Base.Data, texImage->Base.RowStride, i, j, rgba);
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);
texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]);
texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]);
texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]);
diff --git a/mesalib/src/mesa/main/texcompress_rgtc.c b/mesalib/src/mesa/main/texcompress_rgtc.c
index b03cd28b8..3586fc39d 100644
--- a/mesalib/src/mesa/main/texcompress_rgtc.c
+++ b/mesalib/src/mesa/main/texcompress_rgtc.c
@@ -325,7 +325,7 @@ _mesa_fetch_texel_2d_f_red_rgtc1(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 1);
texel[RCOMP] = UBYTE_TO_FLOAT(red);
texel[GCOMP] = 0.0;
@@ -338,7 +338,7 @@ _mesa_fetch_texel_2d_f_signed_red_rgtc1(const struct swrast_texture_image *texIm
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 1);
texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
texel[GCOMP] = 0.0;
@@ -351,9 +351,9 @@ _mesa_fetch_texel_2d_f_rg_rgtc2(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red, green;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 2);
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8,
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data + 8,
i, j, &green, 2);
texel[RCOMP] = UBYTE_TO_FLOAT(red);
texel[GCOMP] = UBYTE_TO_FLOAT(green);
@@ -366,9 +366,9 @@ _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct swrast_texture_image *texIma
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red, green;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 2);
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8,
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data) + 8,
i, j, &green, 2);
texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
@@ -381,7 +381,7 @@ _mesa_fetch_texel_2d_f_l_latc1(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 1);
texel[RCOMP] =
texel[GCOMP] =
@@ -394,7 +394,7 @@ _mesa_fetch_texel_2d_f_signed_l_latc1(const struct swrast_texture_image *texImag
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 1);
texel[RCOMP] =
texel[GCOMP] =
@@ -407,9 +407,9 @@ _mesa_fetch_texel_2d_f_la_latc2(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red, green;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 2);
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8,
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data + 8,
i, j, &green, 2);
texel[RCOMP] =
texel[GCOMP] =
@@ -422,9 +422,9 @@ _mesa_fetch_texel_2d_f_signed_la_latc2(const struct swrast_texture_image *texIma
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red, green;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 2);
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8,
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data) + 8,
i, j, &green, 2);
texel[RCOMP] =
texel[GCOMP] =
diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c
index 904aa457e..ed7eae4f4 100644
--- a/mesalib/src/mesa/main/texcompress_s3tc.c
+++ b/mesalib/src/mesa/main/texcompress_s3tc.c
@@ -398,8 +398,8 @@ fetch_texel_2d_rgb_dxt1( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgb_dxt1) {
- fetch_ext_rgb_dxt1(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data, i, j, texel);
+ fetch_ext_rgb_dxt1(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgb_dxt1");
@@ -426,8 +426,8 @@ fetch_texel_2d_rgba_dxt1( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgba_dxt1) {
- fetch_ext_rgba_dxt1(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data, i, j, texel);
+ fetch_ext_rgba_dxt1(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt1\n");
@@ -454,9 +454,8 @@ fetch_texel_2d_rgba_dxt3( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgba_dxt3) {
- fetch_ext_rgba_dxt3(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data,
- i, j, texel);
+ fetch_ext_rgba_dxt3(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt3\n");
@@ -483,9 +482,8 @@ fetch_texel_2d_rgba_dxt5( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgba_dxt5) {
- fetch_ext_rgba_dxt5(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data,
- i, j, texel);
+ fetch_ext_rgba_dxt5(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt5\n");
diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c
index 7f262d6d8..aebe38ee0 100644
--- a/mesalib/src/mesa/main/texformat.c
+++ b/mesalib/src/mesa/main/texformat.c
@@ -34,6 +34,7 @@
#include "context.h"
+#include "enums.h"
#include "mfeatures.h"
#include "mtypes.h"
#include "texcompress.h"
@@ -897,7 +898,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
}
}
- _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
+ _mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()",
+ _mesa_lookup_enum_by_nr(internalFormat));
return MESA_FORMAT_NONE;
}
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 2d06f84bf..798201a60 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -58,27 +58,6 @@
/**
- * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE
- * elsewhere.
- */
-void *
-_mesa_alloc_texmemory(GLsizei bytes)
-{
- return _mesa_align_malloc(bytes, 512);
-}
-
-
-/**
- * Free texture memory allocated with _mesa_alloc_texmemory()
- */
-void
-_mesa_free_texmemory(void *m)
-{
- _mesa_align_free(m);
-}
-
-
-/**
* Return the simple base format for a given internal texture format.
* For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
*
@@ -599,29 +578,6 @@ _mesa_new_texture_image( struct gl_context *ctx )
/**
- * Free texture image data.
- * This function is a fallback called via ctx->Driver.FreeTextureImageBuffer().
- *
- * \param texImage texture image.
- *
- * Free the texture image data if it's not marked as client data.
- */
-void
-_mesa_free_texture_image_data(struct gl_context *ctx,
- struct gl_texture_image *texImage)
-{
- (void) ctx;
-
- if (texImage->Data) {
- /* free the old texture data */
- _mesa_free_texmemory(texImage->Data);
- }
-
- texImage->Data = NULL;
-}
-
-
-/**
* Free a gl_texture_image and associated data.
* This function is a fallback called via ctx->Driver.DeleteTextureImage().
*
@@ -638,11 +594,6 @@ _mesa_delete_texture_image(struct gl_context *ctx,
*/
ASSERT(ctx->Driver.FreeTextureImageBuffer);
ctx->Driver.FreeTextureImageBuffer( ctx, texImage );
-
- ASSERT(texImage->Data == NULL);
- if (texImage->ImageOffsets)
- free(texImage->ImageOffsets);
- free(texImage);
}
@@ -1084,18 +1035,12 @@ clear_teximage_fields(struct gl_texture_image *img)
img->Width = 0;
img->Height = 0;
img->Depth = 0;
- img->RowStride = 0;
- if (img->ImageOffsets) {
- free(img->ImageOffsets);
- img->ImageOffsets = NULL;
- }
img->Width2 = 0;
img->Height2 = 0;
img->Depth2 = 0;
img->WidthLog2 = 0;
img->HeightLog2 = 0;
img->DepthLog2 = 0;
- img->Data = NULL;
img->TexFormat = MESA_FORMAT_NONE;
}
@@ -1123,8 +1068,6 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
GLint border, GLenum internalFormat,
gl_format format)
{
- GLint i;
-
ASSERT(img);
ASSERT(width >= 0);
ASSERT(height >= 0);
@@ -1161,19 +1104,6 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
- /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
- img->RowStride = width;
- /* Allocate the ImageOffsets array and initialize to typical values.
- * We allocate the array for 1D/2D textures too in order to avoid special-
- * case code in the texstore routines.
- */
- if (img->ImageOffsets)
- free(img->ImageOffsets);
- img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
- for (i = 0; i < depth; i++) {
- img->ImageOffsets[i] = i * width * height;
- }
-
img->TexFormat = format;
}
@@ -2409,7 +2339,6 @@ teximage(struct gl_context *ctx, GLuint dims,
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- ASSERT(texImage->Data == NULL);
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
internalFormat, format,
type);
@@ -2548,7 +2477,6 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
} else {
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- ASSERT(texImage->Data == NULL);
ctx->Driver.EGLImageTargetTexture2D(ctx, target,
texObj, texImage, image);
@@ -3370,7 +3298,6 @@ compressedteximage(struct gl_context *ctx, GLuint dims,
gl_format texFormat;
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- ASSERT(texImage->Data == NULL);
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
internalFormat, GL_NONE,
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 6ce0fe92c..fd315bea3 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -36,13 +36,6 @@
#include "formats.h"
-extern void *
-_mesa_alloc_texmemory(GLsizei bytes);
-
-extern void
-_mesa_free_texmemory(void *m);
-
-
/** \name Internal functions */
/*@{*/
@@ -62,10 +55,6 @@ extern void
_mesa_delete_texture_image( struct gl_context *ctx,
struct gl_texture_image *teximage );
-extern void
-_mesa_free_texture_image_data( struct gl_context *ctx,
- struct gl_texture_image *texImage );
-
extern void
_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 1b90cca9b..4d9942ba8 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -543,12 +543,13 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
width /= 2;
}
if (i >= minLevel && i <= maxLevel) {
- if (!t->Image[0][i]) {
- incomplete(t, "1D Image[0][i] == NULL");
+ const struct gl_texture_image *img = t->Image[0][i];
+ if (!img) {
+ incomplete(t, "1D Image[%d] is missing", i);
return;
}
- if (t->Image[0][i]->Width2 != width ) {
- incomplete(t, "1D Image[0][i] bad width");
+ if (img->Width2 != width ) {
+ incomplete(t, "1D Image[%d] bad width %u", i, img->Width2);
return;
}
}
@@ -570,16 +571,17 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
height /= 2;
}
if (i >= minLevel && i <= maxLevel) {
- if (!t->Image[0][i]) {
- incomplete(t, "2D Image[0][i] == NULL");
+ const struct gl_texture_image *img = t->Image[0][i];
+ if (!img) {
+ incomplete(t, "2D Image[%d of %d] is missing", i, maxLevel);
return;
}
- if (t->Image[0][i]->Width2 != width) {
- incomplete(t, "2D Image[0][i] bad width");
+ if (img->Width2 != width) {
+ incomplete(t, "2D Image[%d] bad width %u", i, img->Width2);
return;
}
- if (t->Image[0][i]->Height2 != height) {
- incomplete(t, "2D Image[0][i] bad height");
+ if (img->Height2 != height) {
+ incomplete(t, "2D Image[i] bad height %u", i, img->Height2);
return;
}
if (width==1 && height==1) {
@@ -604,24 +606,25 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
depth /= 2;
}
if (i >= minLevel && i <= maxLevel) {
- if (!t->Image[0][i]) {
- incomplete(t, "3D Image[0][i] == NULL");
+ const struct gl_texture_image *img = t->Image[0][i];
+ if (!img) {
+ incomplete(t, "3D Image[%d] is missing", i);
return;
}
- if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
+ if (img->_BaseFormat == GL_DEPTH_COMPONENT) {
incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
return;
}
- if (t->Image[0][i]->Width2 != width) {
- incomplete(t, "3D Image[0][i] bad width");
+ if (img->Width2 != width) {
+ incomplete(t, "3D Image[%d] bad width %u", i, img->Width2);
return;
}
- if (t->Image[0][i]->Height2 != height) {
- incomplete(t, "3D Image[0][i] bad height");
+ if (img->Height2 != height) {
+ incomplete(t, "3D Image[%d] bad height %u", i, img->Height2);
return;
}
- if (t->Image[0][i]->Depth2 != depth) {
- incomplete(t, "3D Image[0][i] bad depth");
+ if (img->Depth2 != depth) {
+ incomplete(t, "3D Image[%d] bad depth %u", i, img->Depth2);
return;
}
}
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index cc9fbc020..cd9249630 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -4906,7 +4906,6 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
ASSERT(texImage->Width > 0);
ASSERT(texImage->Height > 0);
ASSERT(texImage->Depth == 1);
- ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index fecab50f7..bdbb6b938 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -40,6 +40,7 @@
#include "../glsl/program.h"
#include "ir_optimization.h"
#include "ast.h"
+#include "linker.h"
#include "main/mtypes.h"
#include "main/shaderobj.h"
@@ -2587,13 +2588,35 @@ check_resources(const struct gl_context *ctx,
}
}
+class add_uniform_to_shader : public uniform_field_visitor {
+public:
+ add_uniform_to_shader(struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params)
+ : shader_program(shader_program), params(params), next_sampler(0)
+ {
+ /* empty */
+ }
-static int
-add_uniform_to_shader(ir_variable *var,
- struct gl_program_parameter_list *params,
- unsigned int &next_sampler)
+ int process(ir_variable *var)
+ {
+ this->idx = -1;
+ this->uniform_field_visitor::process(var);
+
+ return this->idx;
+ }
+
+private:
+ virtual void visit_field(const glsl_type *type, const char *name);
+
+ struct gl_shader_program *shader_program;
+ struct gl_program_parameter_list *params;
+ int next_sampler;
+ int idx;
+};
+
+void
+add_uniform_to_shader::visit_field(const glsl_type *type, const char *name)
{
- const glsl_type *type = var->type;
unsigned int size;
if (type->is_vector() || type->is_scalar()) {
@@ -2610,10 +2633,9 @@ add_uniform_to_shader(ir_variable *var,
file = PROGRAM_UNIFORM;
}
- int index = _mesa_lookup_parameter_index(params, -1, var->name);
+ int index = _mesa_lookup_parameter_index(params, -1, name);
if (index < 0) {
- index = _mesa_add_parameter(params, file,
- var->name, size, type->gl_type,
+ index = _mesa_add_parameter(params, file, name, size, type->gl_type,
NULL, NULL, 0x0);
/* Sampler uniform values are stored in prog->SamplerUnits,
@@ -2622,11 +2644,15 @@ add_uniform_to_shader(ir_variable *var,
*/
if (file == PROGRAM_SAMPLER) {
for (unsigned int j = 0; j < size / 4; j++)
- params->ParameterValues[index + j][0].f = next_sampler++;
+ params->ParameterValues[index + j][0].f = this->next_sampler++;
}
}
- return index;
+ /* The first part of the uniform that's processed determines the base
+ * location of the whole uniform (for structures).
+ */
+ if (this->idx < 0)
+ this->idx = index;
}
/**
@@ -2644,7 +2670,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
struct gl_program_parameter_list
*params)
{
- unsigned int next_sampler = 0;
+ add_uniform_to_shader add(shader_program, params);
foreach_list(node, sh->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
@@ -2653,7 +2679,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
|| (strncmp(var->name, "gl_", 3) == 0))
continue;
- int loc = add_uniform_to_shader(var, params, next_sampler);
+ int loc = add.process(var);
/* The location chosen in the Parameters list here (returned from
* _mesa_add_parameter) has to match what the linker chose.
@@ -3212,7 +3238,9 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
- progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress;
+ progress = do_common_optimization(ir, true, true,
+ options->MaxUnrollIterations)
+ || progress;
progress = lower_quadop_vector(ir, true) || progress;
@@ -3321,7 +3349,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
/* Do some optimization at compile time to reduce shader IR size
* and reduce later work if the same shader is linked multiple times
*/
- while (do_common_optimization(shader->ir, false, 32))
+ while (do_common_optimization(shader->ir, false, false, 32))
;
validate_ir_tree(shader->ir);
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h
index 0a3220221..c60780989 100644
--- a/mesalib/src/mesa/state_tracker/st_context.h
+++ b/mesalib/src/mesa/state_tracker/st_context.h
@@ -75,6 +75,7 @@ struct st_context
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */
struct draw_stage *rastpos_stage; /**< For glRasterPos */
+ GLboolean sw_primitive_restart;
/* On old libGL's for linux we need to invalidate the drawables
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index 574802084..ff3008a5f 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -353,9 +353,26 @@ setup_interleaved_attribs(struct gl_context *ctx,
struct pipe_context *pipe = st->pipe;
GLuint attr;
const GLubyte *low_addr = NULL;
-
- /* Find the lowest address of the arrays we're drawing */
+ GLboolean usingVBO; /* all arrays in a VBO? */
+ struct gl_buffer_object *bufobj;
+ GLuint user_buffer_size = 0;
+ GLuint vertex_size = 0; /* bytes per vertex, in bytes */
+ GLsizei stride;
+
+ /* Find the lowest address of the arrays we're drawing,
+ * Init bufobj and stride.
+ */
if (vpv->num_inputs) {
+ const GLuint mesaAttr0 = vp->index_to_input[0];
+ const struct gl_client_array *array = arrays[mesaAttr0];
+
+ /* Since we're doing interleaved arrays, we know there'll be at most
+ * one buffer object and the stride will be the same for all arrays.
+ * Grab them now.
+ */
+ bufobj = array->BufferObj;
+ stride = array->StrideB;
+
low_addr = arrays[vp->index_to_input[0]]->Ptr;
for (attr = 1; attr < vpv->num_inputs; attr++) {
@@ -363,44 +380,24 @@ setup_interleaved_attribs(struct gl_context *ctx,
low_addr = MIN2(low_addr, start);
}
}
+ else {
+ /* not sure we'll ever have zero inputs, but play it safe */
+ bufobj = NULL;
+ stride = 0;
+ low_addr = 0;
+ }
+
+ /* are the arrays in user space? */
+ usingVBO = bufobj && _mesa_is_bufferobj(bufobj);
for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
const struct gl_client_array *array = arrays[mesaAttr];
- struct gl_buffer_object *bufobj = array->BufferObj;
- struct st_buffer_object *stobj = st_buffer_object(bufobj);
unsigned src_offset = (unsigned) (array->Ptr - low_addr);
GLuint element_size = array->_ElementSize;
- GLsizei stride = array->StrideB;
assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
- if (attr == 0) {
- if (bufobj && _mesa_is_bufferobj(bufobj)) {
- vbuffer->buffer = NULL;
- pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
- vbuffer->buffer_offset = pointer_to_offset(low_addr);
- }
- else {
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
- uint bytes = src_offset + stride * last_index + element_size;
-
- vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
- (void*) low_addr,
- bytes,
- PIPE_BIND_VERTEX_BUFFER);
- vbuffer->buffer_offset = 0;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
- st->user_attrib[0].element_size = element_size;
- st->user_attrib[0].stride = stride;
- st->num_user_attribs = 1;
- }
- vbuffer->stride = stride; /* in bytes */
- }
-
velements[attr].src_offset = src_offset;
velements[attr].instance_divisor = array->InstanceDivisor;
velements[attr].vertex_buffer_index = 0;
@@ -409,6 +406,54 @@ setup_interleaved_attribs(struct gl_context *ctx,
array->Format,
array->Normalized);
assert(velements[attr].src_format);
+
+ if (!usingVBO) {
+ /* how many bytes referenced by this attribute array? */
+ uint divisor = array->InstanceDivisor;
+ uint last_index = divisor ? num_instances / divisor : max_index;
+ uint bytes = src_offset + stride * last_index + element_size;
+
+ user_buffer_size = MAX2(user_buffer_size, bytes);
+
+ /* update vertex size */
+ vertex_size = MAX2(vertex_size, src_offset + element_size);
+ }
+ }
+
+ /*
+ * Return the vbuffer info and setup user-space attrib info, if needed.
+ */
+ if (vpv->num_inputs == 0) {
+ /* just defensive coding here */
+ vbuffer->buffer = NULL;
+ vbuffer->buffer_offset = 0;
+ vbuffer->stride = 0;
+ st->num_user_attribs = 0;
+ }
+ else if (usingVBO) {
+ /* all interleaved arrays in a VBO */
+ struct st_buffer_object *stobj = st_buffer_object(bufobj);
+
+ vbuffer->buffer = NULL;
+ pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
+ vbuffer->buffer_offset = pointer_to_offset(low_addr);
+ vbuffer->stride = stride;
+ st->num_user_attribs = 0;
+ }
+ else {
+ /* all interleaved arrays in user memory */
+ vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
+ (void*) low_addr,
+ user_buffer_size,
+ PIPE_BIND_VERTEX_BUFFER);
+ vbuffer->buffer_offset = 0;
+ vbuffer->stride = stride;
+
+ /* Track user vertex buffers. */
+ pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
+ st->user_attrib[0].element_size = vertex_size;
+ st->user_attrib[0].stride = stride;
+ st->num_user_attribs = 1;
}
}
@@ -582,6 +627,127 @@ check_uniforms(struct gl_context *ctx)
}
}
+/** Helper code for primitive restart fallback */
+#define DO_DRAW(pipe, cur_start, cur_count) \
+ do { \
+ info.start = cur_start; \
+ info.count = cur_count; \
+ if (u_trim_pipe_prim(info.mode, &info.count)) { \
+ if (transfer) \
+ pipe_buffer_unmap(pipe, transfer); \
+ pipe->draw_vbo(pipe, &info); \
+ if (transfer) { \
+ ptr = pipe_buffer_map(pipe, ibuffer->buffer, PIPE_TRANSFER_READ, &transfer); \
+ assert(ptr != NULL); \
+ ptr = ADD_POINTERS(ptr, ibuffer->offset); \
+ } \
+ } \
+ } while(0)
+
+/** More helper code for primitive restart fallback */
+#define PRIM_RESTART_LOOP(elements) \
+ do { \
+ for (i = start; i < end; i++) { \
+ if (elements[i] == info.restart_index) { \
+ if (cur_count > 0) { \
+ /* draw elts up to prev pos */ \
+ DO_DRAW(pipe, cur_start, cur_count); \
+ } \
+ /* begin new prim at next elt */ \
+ cur_start = i + 1; \
+ cur_count = 0; \
+ } \
+ else { \
+ cur_count++; \
+ } \
+ } \
+ if (cur_count > 0) { \
+ DO_DRAW(pipe, cur_start, cur_count); \
+ } \
+ } while (0)
+
+static void
+handle_fallback_primitive_restart(struct pipe_context *pipe,
+ const struct _mesa_index_buffer *ib,
+ struct pipe_index_buffer *ibuffer,
+ struct pipe_draw_info *orig_info)
+{
+ const unsigned start = orig_info->start;
+ const unsigned count = orig_info->count;
+ const unsigned end = start + count;
+ struct pipe_draw_info info = *orig_info;
+ struct pipe_transfer *transfer = NULL;
+ unsigned instance, i, cur_start, cur_count;
+ const void *ptr;
+
+ info.primitive_restart = FALSE;
+
+ if (!info.indexed) {
+ /* Splitting the draw arrays call is handled by the VBO module */
+ if (u_trim_pipe_prim(info.mode, &info.count))
+ pipe->draw_vbo(pipe, &info);
+
+ return;
+ }
+
+ /* info.indexed == TRUE */
+ assert(ibuffer);
+ assert(ibuffer->buffer);
+
+ if (ib) {
+ struct gl_buffer_object *bufobj = ib->obj;
+ if (bufobj && bufobj->Name) {
+ ptr = NULL;
+ }
+ else {
+ ptr = ib->ptr;
+ }
+ } else {
+ ptr = NULL;
+ }
+
+ if (!ptr)
+ ptr = pipe_buffer_map(pipe, ibuffer->buffer, PIPE_TRANSFER_READ, &transfer);
+
+ if (!ptr)
+ return;
+ ptr = ADD_POINTERS(ptr, ibuffer->offset);
+
+ /* Need to loop over instances as well to preserve draw order */
+ for (instance = 0; instance < orig_info->instance_count; instance++) {
+ info.start_instance = instance + orig_info->start_instance;
+ info.instance_count = 1;
+ cur_start = start;
+ cur_count = 0;
+
+ switch (ibuffer->index_size) {
+ case 1:
+ {
+ const ubyte *elt_ub = (const ubyte *)ptr;
+ PRIM_RESTART_LOOP(elt_ub);
+ }
+ break;
+ case 2:
+ {
+ const ushort *elt_us = (const ushort *)ptr;
+ PRIM_RESTART_LOOP(elt_us);
+ }
+ break;
+ case 4:
+ {
+ const uint *elt_ui = (const uint *)ptr;
+ PRIM_RESTART_LOOP(elt_ui);
+ }
+ break;
+ default:
+ assert(0 && "bad index_size in handle_fallback_primitive_restart()");
+ }
+ }
+
+ if (transfer)
+ pipe_buffer_unmap(pipe, transfer);
+}
+
/**
* Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
@@ -794,7 +960,22 @@ st_draw_vbo(struct gl_context *ctx,
info.max_index = info.start + info.count - 1;
}
- if (u_trim_pipe_prim(info.mode, &info.count))
+ if (info.primitive_restart) {
+ /*
+ * Handle primitive restart for drivers that doesn't support it.
+ *
+ * The VBO module handles restart inside of draw_arrays for us,
+ * but we should still remove the primitive_restart flag on the
+ * info struct, the fallback function does this for us. Just
+ * remove the flag for all drivers in this case as well.
+ */
+ if (st->sw_primitive_restart || !info.indexed)
+ handle_fallback_primitive_restart(pipe, ib, &ibuffer, &info);
+ else
+ /* don't trim, restarts might be inside index list */
+ pipe->draw_vbo(pipe, &info);
+ }
+ else if (u_trim_pipe_prim(info.mode, &info.count))
pipe->draw_vbo(pipe, &info);
}
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index a1f029089..37f36de93 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -555,8 +555,9 @@ void st_init_extensions(struct st_context *st)
#endif
}
- if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
- ctx->Extensions.NV_primitive_restart = GL_TRUE;
+ ctx->Extensions.NV_primitive_restart = GL_TRUE;
+ if (!screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
+ st->sw_primitive_restart = GL_TRUE;
}
if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 18e8a1db4..145bd7dcd 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -4322,37 +4322,15 @@ compile_tgsi_instruction(struct st_translate *t,
}
/**
- * Emit the TGSI instructions to adjust the WPOS pixel center convention
- * Basically, add (adjX, adjY) to the fragment position.
- */
-static void
-emit_adjusted_wpos(struct st_translate *t,
- const struct gl_program *program,
- float adjX, float adjY)
-{
- struct ureg_program *ureg = t->ureg;
- struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg);
- struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
-
- /* Note that we bias X and Y and pass Z and W through unchanged.
- * The shader might also use gl_FragCoord.w and .z.
- */
- ureg_ADD(ureg, wpos_temp, wpos_input,
- ureg_imm4f(ureg, adjX, adjY, 0.0f, 0.0f));
-
- t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
-}
-
-
-/**
- * Emit the TGSI instructions for inverting the WPOS y coordinate.
+ * Emit the TGSI instructions for inverting and adjusting WPOS.
* This code is unavoidable because it also depends on whether
* a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
*/
static void
-emit_wpos_inversion(struct st_translate *t,
- const struct gl_program *program,
- bool invert)
+emit_wpos_adjustment( struct st_translate *t,
+ const struct gl_program *program,
+ boolean invert,
+ GLfloat adjX, GLfloat adjY[2])
{
struct ureg_program *ureg = t->ureg;
@@ -4371,35 +4349,55 @@ emit_wpos_inversion(struct st_translate *t,
unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
wposTransformState);
- struct ureg_src wpostrans = ureg_DECL_constant(ureg, wposTransConst);
- struct ureg_dst wpos_temp;
+ struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
+ struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
- /* MOV wpos_temp, input[wpos]
- */
- if (wpos_input.File == TGSI_FILE_TEMPORARY)
- wpos_temp = ureg_dst(wpos_input);
- else {
- wpos_temp = ureg_DECL_temporary(ureg);
- ureg_MOV(ureg, wpos_temp, wpos_input);
+ /* First, apply the coordinate shift: */
+ if (adjX || adjY[0] || adjY[1]) {
+ if (adjY[0] != adjY[1]) {
+ /* Adjust the y coordinate by adjY[1] or adjY[0] respectively
+ * depending on whether inversion is actually going to be applied
+ * or not, which is determined by testing against the inversion
+ * state variable used below, which will be either +1 or -1.
+ */
+ struct ureg_dst adj_temp = ureg_DECL_temporary(ureg);
+
+ ureg_CMP(ureg, adj_temp,
+ ureg_scalar(wpostrans, invert ? 2 : 0),
+ ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f),
+ ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f));
+ ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp));
+ } else {
+ ureg_ADD(ureg, wpos_temp, wpos_input,
+ ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f));
+ }
+ wpos_input = ureg_src(wpos_temp);
+ } else {
+ /* MOV wpos_temp, input[wpos]
+ */
+ ureg_MOV( ureg, wpos_temp, wpos_input );
}
+ /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be
+ * inversion/identity, or the other way around if we're drawing to an FBO.
+ */
if (invert) {
/* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy
*/
- ureg_MAD(ureg,
- ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y),
- wpos_input,
- ureg_scalar(wpostrans, 0),
- ureg_scalar(wpostrans, 1));
+ ureg_MAD( ureg,
+ ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+ wpos_input,
+ ureg_scalar(wpostrans, 0),
+ ureg_scalar(wpostrans, 1));
} else {
/* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
*/
- ureg_MAD(ureg,
- ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y),
- wpos_input,
- ureg_scalar(wpostrans, 2),
- ureg_scalar(wpostrans, 3));
+ ureg_MAD( ureg,
+ ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+ wpos_input,
+ ureg_scalar(wpostrans, 2),
+ ureg_scalar(wpostrans, 3));
}
/* Use wpos_temp as position input from here on:
@@ -4420,8 +4418,37 @@ emit_wpos(struct st_context *st,
const struct gl_fragment_program *fp =
(const struct gl_fragment_program *) program;
struct pipe_screen *pscreen = st->pipe->screen;
+ GLfloat adjX = 0.0f;
+ GLfloat adjY[2] = { 0.0f, 0.0f };
boolean invert = FALSE;
+ /* Query the pixel center conventions supported by the pipe driver and set
+ * adjX, adjY to help out if it cannot handle the requested one internally.
+ *
+ * The bias of the y-coordinate depends on whether y-inversion takes place
+ * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are
+ * drawing to an FBO (causes additional inversion), and whether the the pipe
+ * driver origin and the requested origin differ (the latter condition is
+ * stored in the 'invert' variable).
+ *
+ * For height = 100 (i = integer, h = half-integer, l = lower, u = upper):
+ *
+ * center shift only:
+ * i -> h: +0.5
+ * h -> i: -0.5
+ *
+ * inversion only:
+ * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99
+ * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5
+ * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0
+ * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5
+ *
+ * inversion and center shift:
+ * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5
+ * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99
+ * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5
+ * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0
+ */
if (fp->OriginUpperLeft) {
/* Fragment shader wants origin in upper-left */
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
@@ -4449,12 +4476,17 @@ emit_wpos(struct st_context *st,
if (fp->PixelCenterInteger) {
/* Fragment shader wants pixel center integer */
- if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER))
+ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
/* the driver supports pixel center integer */
+ adjY[1] = 1.0f;
ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
- else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER))
+ }
+ else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
/* the driver supports pixel center half integer, need to bias X,Y */
- emit_adjusted_wpos(t, program, 0.5f, invert ? 0.5f : -0.5f);
+ adjX = -0.5f;
+ adjY[0] = -0.5f;
+ adjY[1] = 0.5f;
+ }
else
assert(0);
}
@@ -4465,8 +4497,8 @@ emit_wpos(struct st_context *st,
}
else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
/* the driver supports pixel center integer, need to bias X,Y */
+ adjX = adjY[0] = adjY[1] = 0.5f;
ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
- emit_adjusted_wpos(t, program, 0.5f, invert ? -0.5f : 0.5f);
}
else
assert(0);
@@ -4474,7 +4506,7 @@ emit_wpos(struct st_context *st,
/* we invert after adjustment so that we avoid the MOV to temporary,
* and reuse the adjustment ADD instead */
- emit_wpos_inversion(t, program, invert);
+ emit_wpos_adjustment(t, program, invert, adjX, adjY);
}
/**
@@ -5026,7 +5058,9 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
- progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress;
+ progress = do_common_optimization(ir, true, true,
+ options->MaxUnrollIterations)
+ || progress;
progress = lower_quadop_vector(ir, false) || progress;
diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c
index 5287671d7..9112cf30d 100644
--- a/mesalib/src/mesa/swrast/s_context.c
+++ b/mesalib/src/mesa/swrast/s_context.c
@@ -747,6 +747,12 @@ _swrast_CreateContext( struct gl_context *ctx )
swrast->AllowVertexFog = GL_TRUE;
swrast->AllowPixelFog = GL_TRUE;
+ swrast->Driver.SpanRenderStart = _swrast_span_render_start;
+ swrast->Driver.SpanRenderFinish = _swrast_span_render_finish;
+
+ ctx->Driver.MapTexture = _swrast_map_texture;
+ ctx->Driver.UnmapTexture = _swrast_unmap_texture;
+
/* Optimized Accum buffer */
swrast->_IntegerAccumMode = GL_FALSE;
swrast->_IntegerAccumScaler = 0.0;
@@ -837,6 +843,24 @@ _swrast_render_primitive( struct gl_context *ctx, GLenum prim )
}
+/** called via swrast->Driver.SpanRenderStart() */
+void
+_swrast_span_render_start(struct gl_context *ctx)
+{
+ _swrast_map_textures(ctx);
+ _swrast_map_renderbuffers(ctx);
+}
+
+
+/** called via swrast->Driver.SpanRenderFinish() */
+void
+_swrast_span_render_finish(struct gl_context *ctx)
+{
+ _swrast_unmap_textures(ctx);
+ _swrast_unmap_renderbuffers(ctx);
+}
+
+
void
_swrast_render_start( struct gl_context *ctx )
{
diff --git a/mesalib/src/mesa/swrast/s_context.h b/mesalib/src/mesa/swrast/s_context.h
index ec8451eb8..d3ba37819 100644
--- a/mesalib/src/mesa/swrast/s_context.h
+++ b/mesalib/src/mesa/swrast/s_context.h
@@ -138,20 +138,17 @@ struct swrast_texture_image
/** used for mipmap LOD computation */
GLfloat WidthScale, HeightScale, DepthScale;
-#if 0
- GLubyte *Data; /**< The actual texture data in malloc'd memory */
+ /** These fields only valid when texture memory is mapped */
+ GLint RowStride; /**< Padded width in units of texels */
+ GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
+ each 2D slice in 'Data', in texels */
+ GLubyte *Data; /**< Image data, accessed via FetchTexel() */
- GLint TexelSize; /**< bytes per texel block */
-#endif
+ /** Malloc'd texture memory */
+ GLubyte *Buffer;
FetchTexelFunc FetchTexel;
StoreTexelFunc Store;
-
-#if 0
- /** These fields only valid when texture memory is mapped */
- GLubyte **SliceMaps; /**< points to OneMap or a malloc'd array */
- GLint RowStride; /**< bytes per row of blocks */
-#endif
};
@@ -339,6 +336,31 @@ swrast_render_finish(struct gl_context *ctx)
}
+extern void
+_swrast_span_render_start(struct gl_context *ctx);
+
+extern void
+_swrast_span_render_finish(struct gl_context *ctx);
+
+extern void
+_swrast_map_textures(struct gl_context *ctx);
+
+extern void
+_swrast_unmap_textures(struct gl_context *ctx);
+
+extern void
+_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj);
+
+extern void
+_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj);
+
+
+extern void
+_swrast_map_renderbuffers(struct gl_context *ctx);
+
+extern void
+_swrast_unmap_renderbuffers(struct gl_context *ctx);
+
/**
* Size of an RGBA pixel, in bytes, for given datatype.
diff --git a/mesalib/src/mesa/swrast/s_fragprog.c b/mesalib/src/mesa/swrast/s_fragprog.c
index 7f205a200..1caa0ebc2 100644
--- a/mesalib/src/mesa/swrast/s_fragprog.c
+++ b/mesalib/src/mesa/swrast/s_fragprog.c
@@ -237,7 +237,8 @@ run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end)
else if (depth >= 1.0)
span->array->z[i] = ctx->DrawBuffer->_DepthMax;
else
- span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF);
+ span->array->z[i] =
+ (GLuint) (depth * ctx->DrawBuffer->_DepthMaxF + 0.5F);
}
}
else {
diff --git a/mesalib/src/mesa/swrast/s_span.c b/mesalib/src/mesa/swrast/s_span.c
index e517c9ae1..4124e444e 100644
--- a/mesalib/src/mesa/swrast/s_span.c
+++ b/mesalib/src/mesa/swrast/s_span.c
@@ -1251,7 +1251,10 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
4 * span->end * sizeof(GLchan));
}
- ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB ||
+ ASSERT(rb->_BaseFormat == GL_RGBA ||
+ rb->_BaseFormat == GL_RGB ||
+ rb->_BaseFormat == GL_RED ||
+ rb->_BaseFormat == GL_RG ||
rb->_BaseFormat == GL_ALPHA);
if (ctx->Color.ColorLogicOpEnabled) {
diff --git a/mesalib/src/mesa/swrast/s_texcombine.c b/mesalib/src/mesa/swrast/s_texcombine.c
index c67c356c1..a7cbb4424 100644
--- a/mesalib/src/mesa/swrast/s_texcombine.c
+++ b/mesalib/src/mesa/swrast/s_texcombine.c
@@ -108,6 +108,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,
i--;
}
_mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
+ free(rgba);
return;
}
}
diff --git a/mesalib/src/mesa/swrast/s_texfetch_tmp.h b/mesalib/src/mesa/swrast/s_texfetch_tmp.h
index c63b2043c..8b7e930f9 100644
--- a/mesalib/src/mesa/swrast/s_texfetch_tmp.h
+++ b/mesalib/src/mesa/swrast/s_texfetch_tmp.h
@@ -43,7 +43,7 @@
#if DIM == 1
#define TEXEL_ADDR( type, image, i, j, k, size ) \
- ((void) (j), (void) (k), ((type *)(image)->Base.Data + (i) * (size)))
+ ((void) (j), (void) (k), ((type *)(image)->Data + (i) * (size)))
#define FETCH(x) fetch_texel_1d_##x
@@ -51,15 +51,15 @@
#define TEXEL_ADDR( type, image, i, j, k, size ) \
((void) (k), \
- ((type *)(image)->Base.Data + ((image)->Base.RowStride * (j) + (i)) * (size)))
+ ((type *)(image)->Data + ((image)->RowStride * (j) + (i)) * (size)))
#define FETCH(x) fetch_texel_2d_##x
#elif DIM == 3
#define TEXEL_ADDR( type, image, i, j, k, size ) \
- ((type *)(image)->Base.Data + ((image)->Base.ImageOffsets[k] \
- + (image)->Base.RowStride * (j) + (i)) * (size))
+ ((type *)(image)->Data + ((image)->ImageOffsets[k] \
+ + (image)->RowStride * (j) + (i)) * (size))
#define FETCH(x) fetch_texel_3d_##x
diff --git a/mesalib/src/mesa/swrast/s_texfilter.c b/mesalib/src/mesa/swrast/s_texfilter.c
index f8b0fa1aa..9de5c0276 100644
--- a/mesalib/src/mesa/swrast/s_texfilter.c
+++ b/mesalib/src/mesa/swrast/s_texfilter.c
@@ -1375,7 +1375,7 @@ opt_sample_rgb_2d(struct gl_context *ctx,
GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
GLint pos = (j << shift) | i;
- GLubyte *texel = ((GLubyte *) img->Data) + 3*pos;
+ GLubyte *texel = swImg->Data + 3 * pos;
rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]);
rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]);
rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]);
@@ -1419,7 +1419,7 @@ opt_sample_rgba_2d(struct gl_context *ctx,
const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
const GLint pos = (row << shift) | col;
- const GLuint texel = *((GLuint *) img->Data + pos);
+ const GLuint texel = *((GLuint *) swImg->Data + pos);
rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) );
rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff );
rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff );
@@ -1442,7 +1442,7 @@ sample_lambda_2d(struct gl_context *ctx,
const GLboolean repeatNoBorderPOT = (tObj->Sampler.WrapS == GL_REPEAT)
&& (tObj->Sampler.WrapT == GL_REPEAT)
- && (tImg->Border == 0 && (tImg->Width == tImg->RowStride))
+ && (tImg->Border == 0 && (tImg->Width == swImg->RowStride))
&& swImg->_IsPowerOfTwo;
ASSERT(lambda != NULL);
diff --git a/mesalib/src/mesa/swrast/s_texrender.c b/mesalib/src/mesa/swrast/s_texrender.c
index 47e458e1c..e2b921512 100644
--- a/mesalib/src/mesa/swrast/s_texrender.c
+++ b/mesalib/src/mesa/swrast/s_texrender.c
@@ -31,6 +31,15 @@ struct texture_renderbuffer
};
+/** cast wrapper */
+static inline struct texture_renderbuffer *
+texture_renderbuffer(struct gl_renderbuffer *rb)
+{
+ return (struct texture_renderbuffer *) rb;
+}
+
+
+
/**
* Get row of values from the renderbuffer that wraps a texture image.
*/
@@ -38,8 +47,7 @@ static void
texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, void *values)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -107,8 +115,7 @@ static void
texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
const GLint x[], const GLint y[], void *values)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -174,8 +181,7 @@ static void
texture_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -236,8 +242,7 @@ static void
texture_put_row_rgb(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -296,8 +301,7 @@ static void
texture_put_mono_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, const void *value, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -356,8 +360,7 @@ texture_put_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
const GLint x[], const GLint y[], const void *values,
const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -415,8 +418,7 @@ texture_put_mono_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
GLuint count, const GLint x[], const GLint y[],
const void *value, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -610,7 +612,6 @@ update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
trb->Base.DataType = CHAN_TYPE;
trb->Base._BaseFormat = GL_RGBA;
}
- trb->Base.Data = trb->TexImage->Base.Data;
}
diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c
index 36b429cfa..fb1edb318 100644
--- a/mesalib/src/mesa/swrast/s_texture.c
+++ b/mesalib/src/mesa/swrast/s_texture.c
@@ -69,14 +69,32 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx,
{
struct swrast_texture_image *swImg = swrast_texture_image(texImage);
GLuint bytes = _mesa_format_image_size(format, width, height, depth);
+ GLuint i;
/* This _should_ be true (revisit if these ever fail) */
assert(texImage->Width == width);
assert(texImage->Height == height);
assert(texImage->Depth == depth);
- assert(!texImage->Data);
- texImage->Data = _mesa_align_malloc(bytes, 512);
+ assert(!swImg->Buffer);
+ swImg->Buffer = _mesa_align_malloc(bytes, 512);
+ if (!swImg->Buffer)
+ return GL_FALSE;
+
+ /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
+ swImg->RowStride = width;
+
+ /* Allocate the ImageOffsets array and initialize to typical values.
+ * We allocate the array for 1D/2D textures too in order to avoid special-
+ * case code in the texstore routines.
+ */
+ swImg->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
+ if (!swImg->ImageOffsets)
+ return GL_FALSE;
+
+ for (i = 0; i < depth; i++) {
+ swImg->ImageOffsets[i] = i * width * height;
+ }
if ((width == 1 || _mesa_is_pow_two(texImage->Width2)) &&
(height == 1 || _mesa_is_pow_two(texImage->Height2)) &&
@@ -98,7 +116,7 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx,
swImg->DepthScale = (GLfloat) texImage->Depth;
}
- return texImage->Data != NULL;
+ return GL_TRUE;
}
@@ -109,11 +127,16 @@ void
_swrast_free_texture_image_buffer(struct gl_context *ctx,
struct gl_texture_image *texImage)
{
- if (texImage->Data) {
- _mesa_align_free(texImage->Data);
+ struct swrast_texture_image *swImage = swrast_texture_image(texImage);
+ if (swImage->Buffer) {
+ _mesa_align_free(swImage->Buffer);
+ swImage->Buffer = NULL;
}
- texImage->Data = NULL;
+ if (swImage->ImageOffsets) {
+ free(swImage->ImageOffsets);
+ swImage->ImageOffsets = NULL;
+ }
}
@@ -155,6 +178,7 @@ _swrast_map_teximage(struct gl_context *ctx,
GLubyte **mapOut,
GLint *rowStrideOut)
{
+ struct swrast_texture_image *swImage = swrast_texture_image(texImage);
GLubyte *map;
GLint stride, texelSize;
GLuint bw, bh;
@@ -165,9 +189,9 @@ _swrast_map_teximage(struct gl_context *ctx,
stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
- assert(texImage->Data);
+ assert(swImage->Buffer);
- map = texImage->Data;
+ map = swImage->Buffer;
if (texImage->TexObject->Target == GL_TEXTURE_3D ||
texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) {
@@ -200,3 +224,138 @@ _swrast_unmap_teximage(struct gl_context *ctx,
{
/* nop */
}
+
+
+void
+_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ const GLuint faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+ GLuint face, level;
+
+ for (face = 0; face < faces; face++) {
+ for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) {
+ struct gl_texture_image *texImage = texObj->Image[face][level];
+ if (texImage) {
+ struct swrast_texture_image *swImage =
+ swrast_texture_image(texImage);
+
+ /* XXX we'll eventually call _swrast_map_teximage() here */
+ swImage->Data = swImage->Buffer;
+ assert(swImage->Buffer);
+ }
+ }
+ }
+}
+
+
+void
+_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ const GLuint faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+ GLuint face, level;
+
+ for (face = 0; face < faces; face++) {
+ for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) {
+ struct gl_texture_image *texImage = texObj->Image[face][level];
+ if (texImage) {
+ struct swrast_texture_image *swImage
+ = swrast_texture_image(texImage);
+
+ /* XXX we'll eventually call _swrast_unmap_teximage() here */
+ swImage->Data = NULL;
+ }
+ }
+ }
+}
+
+
+/**
+ * Map all textures for reading prior to software rendering.
+ */
+void
+_swrast_map_textures(struct gl_context *ctx)
+{
+ GLbitfield enabledUnits = ctx->Texture._EnabledUnits;
+
+ /* loop over enabled texture units */
+ while (enabledUnits) {
+ GLuint unit = _mesa_ffs(enabledUnits) - 1;
+ struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
+
+ _swrast_map_texture(ctx, texObj);
+
+ enabledUnits &= ~(1 << unit);
+ }
+}
+
+
+/**
+ * Unmap all textures for reading prior to software rendering.
+ */
+void
+_swrast_unmap_textures(struct gl_context *ctx)
+{
+ GLbitfield enabledUnits = ctx->Texture._EnabledUnits;
+
+ /* loop over enabled texture units */
+ while (enabledUnits) {
+ GLuint unit = _mesa_ffs(enabledUnits) - 1;
+ struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
+
+ _swrast_unmap_texture(ctx, texObj);
+
+ enabledUnits &= ~(1 << unit);
+ }
+}
+
+
+/**
+ * Map or unmap any textures that we may be rendering to as renderbuffers.
+ */
+static void
+map_unmap_renderbuffers(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLboolean map)
+{
+ GLuint i;
+
+ for (i = 0; i < Elements(fb->Attachment); i++) {
+ struct gl_texture_object *texObj = fb->Attachment[i].Texture;
+ if (texObj) {
+ const GLuint level = fb->Attachment[i].TextureLevel;
+ const GLuint face = fb->Attachment[i].CubeMapFace;
+ struct gl_texture_image *texImage = texObj->Image[face][level];
+ if (texImage) {
+ struct swrast_texture_image *swImage
+ = swrast_texture_image(texImage);
+
+ if (map) {
+ /* XXX we'll eventually call _swrast_map_teximage() here */
+ swImage->Data = swImage->Buffer;
+ }
+ else {
+ /* XXX we'll eventually call _swrast_unmap_teximage() here */
+ swImage->Data = NULL;
+ }
+ }
+ }
+ }
+}
+
+
+void
+_swrast_map_renderbuffers(struct gl_context *ctx)
+{
+ map_unmap_renderbuffers(ctx, ctx->DrawBuffer, GL_TRUE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ map_unmap_renderbuffers(ctx, ctx->ReadBuffer, GL_TRUE);
+}
+
+
+void
+_swrast_unmap_renderbuffers(struct gl_context *ctx)
+{
+ map_unmap_renderbuffers(ctx, ctx->DrawBuffer, GL_FALSE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ map_unmap_renderbuffers(ctx, ctx->ReadBuffer, GL_FALSE);
+}
diff --git a/mesalib/src/mesa/swrast/s_triangle.c b/mesalib/src/mesa/swrast/s_triangle.c
index 839c4fd08..b4f8e7479 100644
--- a/mesalib/src/mesa/swrast/s_triangle.c
+++ b/mesalib/src/mesa/swrast/s_triangle.c
@@ -127,10 +127,12 @@ _swrast_culltriangle( struct gl_context *ctx,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
const GLfloat twidth = (GLfloat) texImg->Width; \
const GLfloat theight = (GLfloat) texImg->Height; \
const GLint twidth_log2 = texImg->WidthLog2; \
- const GLubyte *texture = (const GLubyte *) texImg->Data; \
+ const GLubyte *texture = (const GLubyte *) swImg->Data; \
const GLint smask = texImg->Width - 1; \
const GLint tmask = texImg->Height - 1; \
ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888); \
@@ -181,10 +183,12 @@ _swrast_culltriangle( struct gl_context *ctx,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
const GLfloat twidth = (GLfloat) texImg->Width; \
const GLfloat theight = (GLfloat) texImg->Height; \
const GLint twidth_log2 = texImg->WidthLog2; \
- const GLubyte *texture = (const GLubyte *) texImg->Data; \
+ const GLubyte *texture = (const GLubyte *) swImg->Data; \
const GLint smask = texImg->Width - 1; \
const GLint tmask = texImg->Height - 1; \
ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888); \
@@ -533,9 +537,11 @@ affine_span(struct gl_context *ctx, SWspan *span,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
const GLfloat twidth = (GLfloat) texImg->Width; \
const GLfloat theight = (GLfloat) texImg->Height; \
- info.texture = (const GLchan *) texImg->Data; \
+ info.texture = (const GLchan *) swImg->Data; \
info.twidth_log2 = texImg->WidthLog2; \
info.smask = texImg->Width - 1; \
info.tmask = texImg->Height - 1; \
@@ -800,7 +806,9 @@ fast_persp_span(struct gl_context *ctx, SWspan *span,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
- info.texture = (const GLchan *) texImg->Data; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
+ info.texture = (const GLchan *) swImg->Data; \
info.twidth_log2 = texImg->WidthLog2; \
info.smask = texImg->Width - 1; \
info.tmask = texImg->Height - 1; \
@@ -1062,7 +1070,7 @@ _swrast_choose_triangle( struct gl_context *ctx )
&& texObj2D->_Swizzle == SWIZZLE_NOOP
&& swImg->_IsPowerOfTwo
&& texImg->Border == 0
- && texImg->Width == texImg->RowStride
+ && texImg->Width == swImg->RowStride
&& (format == MESA_FORMAT_RGB888 || format == MESA_FORMAT_RGBA8888)
&& minFilter == magFilter
&& ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
diff --git a/mesalib/src/mesa/tnl/t_vb_program.c b/mesalib/src/mesa/tnl/t_vb_program.c
index 367dfd5bb..836e8e8fa 100644
--- a/mesalib/src/mesa/tnl/t_vb_program.c
+++ b/mesalib/src/mesa/tnl/t_vb_program.c
@@ -68,6 +68,8 @@ struct vp_stage_data {
GLubyte *clipmask; /**< clip flags */
GLubyte ormask, andmask; /**< for clipping */
+ GLboolean vertex_textures;
+
struct gl_program_machine machine;
};
diff --git a/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h
index 9a1b5a127..0b72579a8 100644
--- a/mesalib/src/mesa/vbo/vbo_exec.h
+++ b/mesalib/src/mesa/vbo/vbo_exec.h
@@ -78,9 +78,6 @@ struct vbo_exec_copied_vtx {
};
-typedef void (*vbo_attrfv_func)( const GLfloat * );
-
-
struct vbo_exec_context
{
struct gl_context *ctx;
@@ -113,8 +110,6 @@ struct vbo_exec_context
* values are squashed down to the 32 attributes passed to the
* vertex program below:
*/
- enum vp_mode program_mode;
- GLuint enabled_flags;
const struct gl_client_array *inputs[VERT_ATTRIB_MAX];
} vtx;
@@ -126,10 +121,6 @@ struct vbo_exec_context
} eval;
struct {
- enum vp_mode program_mode;
- GLuint enabled_flags;
- GLuint array_obj;
-
/* These just mirror the current arrayobj (todo: make arrayobj
* look like this and remove the mirror):
*/
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index 4e4f2c947..7023380a1 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -422,8 +422,6 @@ bind_array_obj(struct gl_context *ctx)
assert(i < Elements(exec->array.generic_array));
exec->array.generic_array[i] = &arrayObj->VertexAttrib[i];
}
-
- exec->array.array_obj = arrayObj->Name;
}
@@ -444,10 +442,7 @@ recalculate_input_bindings(struct gl_context *ctx)
GLbitfield const_inputs = 0x0;
GLuint i;
- exec->array.program_mode = get_program_mode(ctx);
- exec->array.enabled_flags = ctx->Array.ArrayObj->_Enabled;
-
- switch (exec->array.program_mode) {
+ switch (get_program_mode(ctx)) {
case VP_NONE:
/* When no vertex program is active (or the vertex program is generated
* from fixed-function state). We put the material values into the
diff --git a/mesalib/src/mesa/vbo/vbo_save.h b/mesalib/src/mesa/vbo/vbo_save.h
index a064090cf..a85a7cbf6 100644
--- a/mesalib/src/mesa/vbo/vbo_save.h
+++ b/mesalib/src/mesa/vbo/vbo_save.h
@@ -146,7 +146,6 @@ struct vbo_save_context {
GLuint vert_count;
GLuint max_vert;
GLboolean dangling_attr_ref;
- GLboolean have_materials;
GLuint opcode_vertex_list;