aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-12-17 13:46:47 +0100
committerMarc Haesen <marc@hc-consult.be>2011-12-17 13:46:47 +0100
commitcd55591be471b59faf9693651837a61e8376d85a (patch)
treedaa8bcdb500384d7112f5114bf9c11b0bc2ab78d
parent1ae4005bfe3690b34ec40e33918b3e24468d47e1 (diff)
parentabacebe06d9f3d2fe1b7d256bd86cddbfa592a85 (diff)
downloadvcxsrv-cd55591be471b59faf9693651837a61e8376d85a.tar.gz
vcxsrv-cd55591be471b59faf9693651837a61e8376d85a.tar.bz2
vcxsrv-cd55591be471b59faf9693651837a61e8376d85a.zip
Merge remote-tracking branch 'origin/released'
-rw-r--r--X11/xtrans/Xtranssock.c14
-rw-r--r--libX11/src/QuColors.c176
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blit.c6
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c105
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.h29
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_debug_describe.c10
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_debug_describe.h100
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_dump_state.c19
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c3
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_inlines.h930
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_simple_shaders.c498
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_simple_shaders.h174
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c47
-rw-r--r--mesalib/src/mesa/main/api_validate.c34
-rw-r--r--mesalib/src/mesa/main/api_validate.h10
-rw-r--r--mesalib/src/mesa/main/dd.h3
-rw-r--r--mesalib/src/mesa/main/dlist.c22
-rw-r--r--mesalib/src/mesa/main/fbobject.c20
-rw-r--r--mesalib/src/mesa/main/format_unpack.c8
-rw-r--r--mesalib/src/mesa/main/mipmap.c128
-rw-r--r--mesalib/src/mesa/main/mipmap.h6
-rw-r--r--mesalib/src/mesa/main/mtypes.h2
-rw-r--r--mesalib/src/mesa/main/texformat.c2
-rw-r--r--mesalib/src/mesa/main/texgetimage.c8
-rw-r--r--mesalib/src/mesa/main/teximage.c11
-rw-r--r--mesalib/src/mesa/main/teximage.h4
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c61
-rw-r--r--mesalib/src/mesa/main/transformfeedback.h6
-rw-r--r--mesalib/src/mesa/main/varray.h7
-rw-r--r--mesalib/src/mesa/main/vtxfmt.c1
-rw-r--r--mesalib/src/mesa/program/prog_parameter_layout.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_rasterizer.c7
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bitmap.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawpixels.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawtex.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_rasterpos.c545
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_xformfb.c331
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_xformfb.h114
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c14
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.h184
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw_feedback.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c15
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp27
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h6
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c12
-rw-r--r--mesalib/src/mesa/swrast/s_blit.c10
-rw-r--r--mesalib/src/mesa/swrast/s_drawpix.c6
-rw-r--r--mesalib/src/mesa/tnl/t_draw.c3
-rw-r--r--mesalib/src/mesa/tnl/tnl.h207
-rw-r--r--mesalib/src/mesa/vbo/vbo.h4
-rw-r--r--mesalib/src/mesa/vbo/vbo_context.h1
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c93
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_draw.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_rebase.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_api.c11
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_draw.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_split_copy.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_split_inplace.c3
-rw-r--r--xorg-server/configure.ac2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c28
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c78
-rw-r--r--xorg-server/hw/xfree86/common/xf86Priv.h1
-rw-r--r--xorg-server/include/xorg-config.h.in6
65 files changed, 2414 insertions, 1767 deletions
diff --git a/X11/xtrans/Xtranssock.c b/X11/xtrans/Xtranssock.c
index bb7ece4c2..3a151ecfe 100644
--- a/X11/xtrans/Xtranssock.c
+++ b/X11/xtrans/Xtranssock.c
@@ -466,6 +466,7 @@ TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, char *port)
XtransConnInfo ciptr;
int portlen;
struct sockaddr *addr;
+ size_t addrlen;
prmsg (3,"SocketReopen(%d,%d,%s)\n", type, fd, port);
@@ -496,26 +497,27 @@ TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, char *port)
ciptr->fd = fd;
- if ((addr = calloc (1, portlen + 2)) == NULL) {
+ addrlen = portlen + offsetof(struct sockaddr, sa_data);
+ if ((addr = calloc (1, addrlen)) == NULL) {
prmsg (1, "SocketReopen: malloc(addr) failed\n");
free (ciptr);
return NULL;
}
ciptr->addr = (char *) addr;
- ciptr->addrlen = portlen + 2;
+ ciptr->addrlen = addrlen;
- if ((ciptr->peeraddr = calloc (1, portlen + 2)) == NULL) {
+ if ((ciptr->peeraddr = calloc (1, addrlen)) == NULL) {
prmsg (1, "SocketReopen: malloc(portaddr) failed\n");
free (addr);
free (ciptr);
return NULL;
}
- ciptr->peeraddrlen = portlen + 2;
+ ciptr->peeraddrlen = addrlen;
/* Initialize ciptr structure as if it were a normally-opened unix socket */
ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK;
#ifdef BSD44SOCKETS
- addr->sa_len = portlen + 1;
+ addr->sa_len = addrlen;
#endif
addr->sa_family = AF_UNIX;
#ifdef HAS_STRLCPY
@@ -524,7 +526,7 @@ TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, char *port)
strncpy(addr->sa_data, port, portlen);
#endif
ciptr->family = AF_UNIX;
- memcpy(ciptr->peeraddr, ciptr->addr, sizeof(struct sockaddr));
+ memcpy(ciptr->peeraddr, ciptr->addr, addrlen);
ciptr->port = rindex(addr->sa_data, ':');
if (ciptr->port == NULL) {
if (is_numeric(addr->sa_data)) {
diff --git a/libX11/src/QuColors.c b/libX11/src/QuColors.c
index 3aa2838ac..237b8bf03 100644
--- a/libX11/src/QuColors.c
+++ b/libX11/src/QuColors.c
@@ -1,77 +1,99 @@
-/*
-
-Copyright 1986, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-
-int
-XQueryColors(
- register Display *dpy,
- Colormap cmap,
- XColor *defs, /* RETURN */
- int ncolors)
-{
- register int i;
- xrgb *color;
- xQueryColorsReply rep;
- long nbytes;
- register xQueryColorsReq *req;
-
- LockDisplay(dpy);
- GetReq(QueryColors, req);
-
- req->cmap = cmap;
- req->length += ncolors; /* each pixel is a CARD32 */
-
- for (i = 0; i < ncolors; i++)
- Data32 (dpy, (long *)&defs[i].pixel, 4L);
- /* XXX this isn't very efficient */
-
- if (_XReply(dpy, (xReply *) &rep, 0, xFalse) != 0) {
- if ((color = (xrgb *)
- Xmalloc((unsigned) (nbytes = (long) ncolors * SIZEOF(xrgb))))) {
-
- _XRead(dpy, (char *) color, nbytes);
-
- for (i = 0; i < ncolors; i++) {
- register XColor *def = &defs[i];
- register xrgb *rgb = &color[i];
- def->red = rgb->red;
- def->green = rgb->green;
- def->blue = rgb->blue;
- def->flags = DoRed | DoGreen | DoBlue;
- }
- Xfree((char *)color);
- }
- else _XEatData(dpy, (unsigned long) nbytes);
- }
- UnlockDisplay(dpy);
- SyncHandle();
- return 1;
-}
-
+/*
+
+Copyright 1986, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+
+static void
+_XQueryColors(
+ register Display *dpy,
+ Colormap cmap,
+ XColor *defs, /* RETURN */
+ int ncolors)
+{
+ register int i;
+ xrgb *color;
+ xQueryColorsReply rep;
+ long nbytes;
+ register xQueryColorsReq *req;
+
+ GetReq(QueryColors, req);
+
+ req->cmap = cmap;
+ SetReqLen(req, ncolors, ncolors); /* each pixel is a CARD32 */
+
+ for (i = 0; i < ncolors; i++)
+ Data32 (dpy, (long *)&defs[i].pixel, 4L);
+ /* XXX this isn't very efficient */
+
+ if (_XReply(dpy, (xReply *) &rep, 0, xFalse) != 0) {
+ if ((color = (xrgb *)
+ Xmalloc((unsigned) (nbytes = (long) ncolors * SIZEOF(xrgb))))) {
+
+ _XRead(dpy, (char *) color, nbytes);
+
+ for (i = 0; i < ncolors; i++) {
+ register XColor *def = &defs[i];
+ register xrgb *rgb = &color[i];
+ def->red = rgb->red;
+ def->green = rgb->green;
+ def->blue = rgb->blue;
+ def->flags = DoRed | DoGreen | DoBlue;
+ }
+ Xfree((char *)color);
+ }
+ else _XEatData(dpy, (unsigned long) nbytes);
+ }
+}
+
+int
+XQueryColors(
+ register Display * const dpy,
+ const Colormap cmap,
+ XColor *defs, /* RETURN */
+ int ncolors)
+{
+ int n;
+
+ if (dpy->bigreq_size > 0)
+ n = dpy->bigreq_size - (sizeof (xQueryColorsReq) >> 2) - 1;
+ else
+ n = dpy->max_request_size - (sizeof (xQueryColorsReq) >> 2);
+
+ LockDisplay(dpy);
+ while (ncolors >= n) {
+ _XQueryColors(dpy, cmap, defs, n);
+ defs += n;
+ ncolors -= n;
+ }
+ if (ncolors > 0)
+ _XQueryColors(dpy, cmap, defs, ncolors);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c
index 3a0d7d424..bba0031d7 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blit.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blit.c
@@ -529,6 +529,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
cso_save_fragment_sampler_views(ctx->cso);
+ cso_save_stream_outputs(ctx->cso);
cso_save_viewport(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
@@ -546,6 +547,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
+ cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
/* sampler */
ctx->sampler.normalized_coords = normalized;
@@ -622,6 +624,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
cso_restore_vertex_buffers(ctx->cso);
+ cso_restore_stream_outputs(ctx->cso);
pipe_sampler_view_reference(&sampler_view, NULL);
if (dst_surface != dst)
@@ -722,6 +725,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
cso_save_fragment_sampler_views(ctx->cso);
+ cso_save_stream_outputs(ctx->cso);
cso_save_viewport(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
@@ -737,6 +741,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
+ cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
/* sampler */
ctx->sampler.normalized_coords = normalized;
@@ -801,4 +806,5 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
cso_restore_vertex_buffers(ctx->cso);
+ cso_restore_stream_outputs(ctx->cso);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index f5cc5cb3b..3c501814e 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -63,6 +63,7 @@ struct blitter_context_priv
/* Constant state objects. */
/* Vertex shaders. */
void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
+ void *vs_pos_only; /**< Vertex shader which passes pos to the output.*/
/* Fragment shaders. */
/* The shader at index i outputs color to color buffers 0,1,...,i-1. */
@@ -87,15 +88,18 @@ struct blitter_context_priv
void *dsa_keep_depth_stencil;
void *dsa_keep_depth_write_stencil;
+ /* Vertex elements states. */
void *velem_state;
void *velem_uint_state;
void *velem_sint_state;
+ void *velem_state_readbuf;
/* Sampler state. */
void *sampler_state;
/* Rasterizer state. */
void *rs_state;
+ void *rs_discard_state;
/* Viewport state. */
struct pipe_viewport_state viewport;
@@ -109,6 +113,7 @@ struct blitter_context_priv
boolean has_geometry_shader;
boolean vertex_has_integers;
+ boolean has_stream_out;
};
static void blitter_draw_rectangle(struct blitter_context *blitter,
@@ -148,6 +153,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->base.saved_num_sampler_views = ~0;
ctx->base.saved_num_sampler_states = ~0;
ctx->base.saved_num_vertex_buffers = ~0;
+ ctx->base.saved_num_so_targets = ~0;
ctx->has_geometry_shader =
pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
@@ -155,6 +161,9 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->vertex_has_integers =
pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_INTEGERS);
+ ctx->has_stream_out =
+ pipe->screen->get_param(pipe->screen,
+ PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
/* blend state objects */
memset(&blend, 0, sizeof(blend));
@@ -205,7 +214,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
- /* vertex elements state */
+ if (ctx->has_stream_out) {
+ rs_state.rasterizer_discard = 1;
+ ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
+ }
+
+ /* vertex elements states */
memset(&velem[0], 0, sizeof(velem[0]) * 2);
for (i = 0; i < 2; i++) {
velem[i].src_offset = i * 4 * sizeof(float);
@@ -229,9 +243,14 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
}
+ if (ctx->has_stream_out) {
+ velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ ctx->velem_state_readbuf = pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
+ }
+
/* fragment shaders are created on-demand */
- /* vertex shader */
+ /* vertex shaders */
{
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_GENERIC };
@@ -240,6 +259,20 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
semantic_indices);
}
+ if (ctx->has_stream_out) {
+ struct pipe_stream_output_info so;
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION };
+ const uint semantic_indices[] = { 0 };
+
+ memset(&so, 0, sizeof(so));
+ so.num_outputs = 1;
+ so.output[0].register_mask = TGSI_WRITEMASK_XYZW;
+ so.stride = 4;
+
+ ctx->vs_pos_only =
+ util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
+ semantic_indices, &so);
+ }
/* set invariant vertex coordinates */
for (i = 0; i < 4; i++)
@@ -269,12 +302,18 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
+ if (ctx->rs_discard_state)
+ pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
pipe->delete_vs_state(pipe, ctx->vs);
+ if (ctx->vs_pos_only)
+ pipe->delete_vs_state(pipe, ctx->vs_pos_only);
pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
if (ctx->vertex_has_integers) {
pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state);
pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state);
}
+ if (ctx->velem_state_readbuf)
+ pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf);
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
if (ctx->fs_texfetch_col[i])
@@ -319,6 +358,7 @@ static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
ctx->base.saved_velem_state != INVALID_PTR &&
ctx->base.saved_vs != INVALID_PTR &&
(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR) &&
+ (!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0) &&
ctx->base.saved_rs_state != INVALID_PTR);
}
@@ -354,6 +394,18 @@ static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
ctx->base.saved_gs = INVALID_PTR;
}
+ /* Stream outputs. */
+ if (ctx->has_stream_out) {
+ pipe->set_stream_output_targets(pipe,
+ ctx->base.saved_num_so_targets,
+ ctx->base.saved_so_targets, ~0);
+
+ for (i = 0; i < ctx->base.saved_num_so_targets; i++)
+ pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
+
+ ctx->base.saved_num_so_targets = ~0;
+ }
+
/* Rasterizer. */
pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
ctx->base.saved_rs_state = INVALID_PTR;
@@ -1160,3 +1212,52 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
blitter_restore_fb_state(ctx);
blitter_unset_running_flag(ctx);
}
+
+void util_blitter_copy_buffer(struct blitter_context *blitter,
+ struct pipe_resource *dst,
+ unsigned dstx,
+ struct pipe_resource *src,
+ unsigned srcx,
+ unsigned size)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->base.pipe;
+ struct pipe_vertex_buffer vb;
+ struct pipe_stream_output_target *so_target;
+
+ /* Drivers not capable of Stream Out should not call this function
+ * in the first place. */
+ assert(ctx->has_stream_out);
+
+ /* Some alignment is required. */
+ if (srcx % 4 != 0 || dstx % 4 != 0 || size % 16 != 0 ||
+ !ctx->has_stream_out) {
+ struct pipe_box box;
+ u_box_1d(srcx, size, &box);
+ util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
+ return;
+ }
+
+ blitter_set_running_flag(ctx);
+ blitter_check_saved_vertex_states(ctx);
+
+ vb.buffer = src;
+ vb.buffer_offset = srcx;
+ vb.stride = 4;
+
+ pipe->set_vertex_buffers(pipe, 1, &vb);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf);
+ pipe->bind_vs_state(pipe, ctx->vs_pos_only);
+ if (ctx->has_geometry_shader)
+ pipe->bind_gs_state(pipe, NULL);
+ pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
+
+ so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
+ pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
+
+ util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 16);
+
+ blitter_restore_vertex_states(ctx);
+ blitter_unset_running_flag(ctx);
+ pipe_so_target_reference(&so_target, NULL);
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h
index 3e1457ae0..f605a7e7a 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.h
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h
@@ -104,6 +104,9 @@ struct blitter_context
int saved_num_vertex_buffers;
struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS];
+
+ int saved_num_so_targets;
+ struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS];
};
/**
@@ -131,6 +134,7 @@ struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)
* - vertex elements
* - vertex shader
* - geometry shader (if supported)
+ * - stream output targets (if supported)
* - rasterizer state
*/
@@ -214,6 +218,17 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
unsigned src_width0, unsigned src_height0);
/**
+ * Copy data from one buffer to another using the Stream Output functionality.
+ * Some alignment is required, otherwise software fallback is used.
+ */
+void util_blitter_copy_buffer(struct blitter_context *blitter,
+ struct pipe_resource *dst,
+ unsigned dstx,
+ struct pipe_resource *src,
+ unsigned srcx,
+ unsigned size);
+
+/**
* 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
@@ -379,6 +394,20 @@ util_blitter_save_vertex_buffers(struct blitter_context *blitter,
num_vertex_buffers);
}
+static INLINE void
+util_blitter_save_so_targets(struct blitter_context *blitter,
+ int num_targets,
+ struct pipe_stream_output_target **targets)
+{
+ unsigned i;
+ assert(num_targets <= Elements(blitter->saved_so_targets));
+
+ blitter->saved_num_so_targets = num_targets;
+ for (i = 0; i < num_targets; i++)
+ pipe_so_target_reference(&blitter->saved_so_targets[i],
+ targets[i]);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_describe.c b/mesalib/src/gallium/auxiliary/util/u_debug_describe.c
index 3574accc0..df73ed83e 100644
--- a/mesalib/src/gallium/auxiliary/util/u_debug_describe.c
+++ b/mesalib/src/gallium/auxiliary/util/u_debug_describe.c
@@ -79,3 +79,13 @@ debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr)
debug_describe_resource(res, ptr->texture);
util_sprintf(buf, "pipe_sampler_view<%s,%s>", res, util_format_short_name(ptr->format));
}
+
+void
+debug_describe_so_target(char* buf,
+ const struct pipe_stream_output_target *ptr)
+{
+ char res[128];
+ debug_describe_resource(res, ptr->buffer);
+ util_sprintf(buf, "pipe_stream_output_target<%s,%u,%u>", res,
+ ptr->buffer_offset, ptr->buffer_size);
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_describe.h b/mesalib/src/gallium/auxiliary/util/u_debug_describe.h
index 447e838e4..4f7882b0b 100644
--- a/mesalib/src/gallium/auxiliary/util/u_debug_describe.h
+++ b/mesalib/src/gallium/auxiliary/util/u_debug_describe.h
@@ -1,49 +1,51 @@
-/**************************************************************************
- *
- * Copyright 2010 Luca Barbieri
- *
- * 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#ifndef U_DEBUG_DESCRIBE_H_
-#define U_DEBUG_DESCRIBE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct pipe_reference;
-struct pipe_resource;
-struct pipe_surface;
-struct pipe_sampler_view;
-
-/* a 256-byte buffer is necessary and sufficient */
-void debug_describe_reference(char* buf, const struct pipe_reference*ptr);
-void debug_describe_resource(char* buf, const struct pipe_resource *ptr);
-void debug_describe_surface(char* buf, const struct pipe_surface *ptr);
-void debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* U_DEBUG_DESCRIBE_H_ */
+/**************************************************************************
+ *
+ * Copyright 2010 Luca Barbieri
+ *
+ * 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+#ifndef U_DEBUG_DESCRIBE_H_
+#define U_DEBUG_DESCRIBE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_reference;
+struct pipe_resource;
+struct pipe_surface;
+struct pipe_sampler_view;
+
+/* a 256-byte buffer is necessary and sufficient */
+void debug_describe_reference(char* buf, const struct pipe_reference*ptr);
+void debug_describe_resource(char* buf, const struct pipe_resource *ptr);
+void debug_describe_surface(char* buf, const struct pipe_surface *ptr);
+void debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr);
+void debug_describe_so_target(char* buf,
+ const struct pipe_stream_output_target *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* U_DEBUG_DESCRIBE_H_ */
diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c
index 917d7cd35..91f4aae69 100644
--- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c
+++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c
@@ -423,6 +423,7 @@ void
util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state)
{
char str[8192];
+ unsigned i;
if(!state) {
util_dump_null(stream);
@@ -437,6 +438,24 @@ util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state)
util_dump_string(stream, str);
util_dump_member_end(stream);
+ util_dump_member_begin(stream, "stream_output");
+ util_dump_struct_begin(stream, "pipe_stream_output_info");
+ util_dump_member(stream, uint, &state->stream_output, num_outputs);
+ util_dump_member(stream, uint, &state->stream_output, stride);
+ util_dump_array_begin(stream);
+ for(i = 0; i < state->stream_output.num_outputs; ++i) {
+ util_dump_elem_begin(stream);
+ util_dump_struct_begin(stream, ""); /* anonymous */
+ util_dump_member(stream, uint, &state->stream_output.output[i], register_index);
+ util_dump_member(stream, uint, &state->stream_output.output[i], register_mask);
+ util_dump_member(stream, uint, &state->stream_output.output[i], output_buffer);
+ util_dump_struct_end(stream);
+ util_dump_elem_end(stream);
+ }
+ util_dump_array_end(stream);
+ util_dump_struct_end(stream);
+ util_dump_member_end(stream);
+
util_dump_struct_end(stream);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c
index 436a0e424..7cce815be 100644
--- a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1558,6 +1558,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
cso_save_fragment_sampler_views(ctx->cso);
+ cso_save_stream_outputs(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
@@ -1572,6 +1573,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
+ cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
set_fragment_shader(ctx, type);
set_vertex_shader(ctx);
@@ -1688,4 +1690,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_restore_viewport(ctx->cso);
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
+ cso_restore_stream_outputs(ctx->cso);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h
index ad47439d0..44283909a 100644
--- a/mesalib/src/gallium/auxiliary/util/u_inlines.h
+++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h
@@ -1,459 +1,471 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#ifndef U_INLINES_H
-#define U_INLINES_H
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "pipe/p_screen.h"
-#include "util/u_debug.h"
-#include "util/u_debug_describe.h"
-#include "util/u_debug_refcnt.h"
-#include "util/u_atomic.h"
-#include "util/u_box.h"
-#include "util/u_math.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Reference counting helper functions.
- */
-
-
-static INLINE void
-pipe_reference_init(struct pipe_reference *reference, unsigned count)
-{
- p_atomic_set(&reference->count, count);
-}
-
-static INLINE boolean
-pipe_is_referenced(struct pipe_reference *reference)
-{
- return p_atomic_read(&reference->count) != 0;
-}
-
-/**
- * Update reference counting.
- * The old thing pointed to, if any, will be unreferenced.
- * Both 'ptr' and 'reference' may be NULL.
- * \return TRUE if the object's refcount hits zero and should be destroyed.
- */
-static INLINE boolean
-pipe_reference_described(struct pipe_reference *ptr,
- struct pipe_reference *reference,
- debug_reference_descriptor get_desc)
-{
- boolean destroy = FALSE;
-
- if(ptr != reference) {
- /* bump the reference.count first */
- if (reference) {
- assert(pipe_is_referenced(reference));
- p_atomic_inc(&reference->count);
- debug_reference(reference, get_desc, 1);
- }
-
- if (ptr) {
- assert(pipe_is_referenced(ptr));
- if (p_atomic_dec_zero(&ptr->count)) {
- destroy = TRUE;
- }
- debug_reference(ptr, get_desc, -1);
- }
- }
-
- return destroy;
-}
-
-static INLINE boolean
-pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
-{
- return pipe_reference_described(ptr, reference,
- (debug_reference_descriptor)debug_describe_reference);
-}
-
-static INLINE void
-pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
-{
- struct pipe_surface *old_surf = *ptr;
-
- if (pipe_reference_described(&(*ptr)->reference, &surf->reference,
- (debug_reference_descriptor)debug_describe_surface))
- old_surf->context->surface_destroy(old_surf->context, old_surf);
- *ptr = surf;
-}
-
-static INLINE void
-pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex)
-{
- struct pipe_resource *old_tex = *ptr;
-
- if (pipe_reference_described(&(*ptr)->reference, &tex->reference,
- (debug_reference_descriptor)debug_describe_resource))
- old_tex->screen->resource_destroy(old_tex->screen, old_tex);
- *ptr = tex;
-}
-
-static INLINE void
-pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view)
-{
- struct pipe_sampler_view *old_view = *ptr;
-
- if (pipe_reference_described(&(*ptr)->reference, &view->reference,
- (debug_reference_descriptor)debug_describe_sampler_view))
- old_view->context->sampler_view_destroy(old_view->context, old_view);
- *ptr = view;
-}
-
-static INLINE void
-pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps,
- struct pipe_resource *pt, unsigned level, unsigned layer,
- unsigned flags)
-{
- pipe_resource_reference(&ps->texture, pt);
- ps->format = pt->format;
- ps->width = u_minify(pt->width0, level);
- ps->height = u_minify(pt->height0, level);
- ps->usage = flags;
- ps->u.tex.level = level;
- ps->u.tex.first_layer = ps->u.tex.last_layer = layer;
- ps->context = ctx;
-}
-
-static INLINE void
-pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps,
- struct pipe_resource *pt, unsigned level, unsigned layer,
- unsigned flags)
-{
- ps->texture = 0;
- pipe_reference_init(&ps->reference, 1);
- pipe_surface_reset(ctx, ps, pt, level, layer, flags);
-}
-
-/* Return true if the surfaces are equal. */
-static INLINE boolean
-pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2)
-{
- return s1->texture == s2->texture &&
- s1->format == s2->format &&
- (s1->texture->target != PIPE_BUFFER ||
- (s1->u.buf.first_element == s2->u.buf.first_element &&
- s1->u.buf.last_element == s2->u.buf.last_element)) &&
- (s1->texture->target == PIPE_BUFFER ||
- (s1->u.tex.level == s2->u.tex.level &&
- s1->u.tex.first_layer == s2->u.tex.first_layer &&
- s1->u.tex.last_layer == s2->u.tex.last_layer));
-}
-
-/*
- * Convenience wrappers for screen buffer functions.
- */
-
-static INLINE struct pipe_resource *
-pipe_buffer_create( struct pipe_screen *screen,
- unsigned bind,
- unsigned usage,
- unsigned size )
-{
- struct pipe_resource buffer;
- memset(&buffer, 0, sizeof buffer);
- buffer.target = PIPE_BUFFER;
- buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
- buffer.bind = bind;
- buffer.usage = usage;
- buffer.flags = 0;
- buffer.width0 = size;
- buffer.height0 = 1;
- buffer.depth0 = 1;
- buffer.array_size = 1;
- return screen->resource_create(screen, &buffer);
-}
-
-
-static INLINE struct pipe_resource *
-pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size,
- unsigned usage )
-{
- return screen->user_buffer_create(screen, ptr, size, usage);
-}
-
-static INLINE void *
-pipe_buffer_map_range(struct pipe_context *pipe,
- struct pipe_resource *buffer,
- unsigned offset,
- unsigned length,
- unsigned usage,
- struct pipe_transfer **transfer)
-{
- struct pipe_box box;
- void *map;
-
- assert(offset < buffer->width0);
- assert(offset + length <= buffer->width0);
- assert(length);
-
- u_box_1d(offset, length, &box);
-
- *transfer = pipe->get_transfer( pipe,
- buffer,
- 0,
- usage,
- &box);
-
- if (*transfer == NULL)
- return NULL;
-
- map = pipe->transfer_map( pipe, *transfer );
- if (map == NULL) {
- pipe->transfer_destroy( pipe, *transfer );
- *transfer = NULL;
- return NULL;
- }
-
- /* Match old screen->buffer_map_range() behaviour, return pointer
- * to where the beginning of the buffer would be:
- */
- return (void *)((char *)map - offset);
-}
-
-
-static INLINE void *
-pipe_buffer_map(struct pipe_context *pipe,
- struct pipe_resource *buffer,
- unsigned usage,
- struct pipe_transfer **transfer)
-{
- return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer);
-}
-
-
-static INLINE void
-pipe_buffer_unmap(struct pipe_context *pipe,
- struct pipe_transfer *transfer)
-{
- if (transfer) {
- pipe->transfer_unmap(pipe, transfer);
- pipe->transfer_destroy(pipe, transfer);
- }
-}
-
-static INLINE void
-pipe_buffer_flush_mapped_range(struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- unsigned offset,
- unsigned length)
-{
- struct pipe_box box;
- int transfer_offset;
-
- assert(length);
- assert(transfer->box.x <= offset);
- assert(offset + length <= transfer->box.x + transfer->box.width);
-
- /* Match old screen->buffer_flush_mapped_range() behaviour, where
- * offset parameter is relative to the start of the buffer, not the
- * mapped range.
- */
- transfer_offset = offset - transfer->box.x;
-
- u_box_1d(transfer_offset, length, &box);
-
- pipe->transfer_flush_region(pipe, transfer, &box);
-}
-
-static INLINE void
-pipe_buffer_write(struct pipe_context *pipe,
- struct pipe_resource *buf,
- unsigned offset,
- unsigned size,
- const void *data)
-{
- struct pipe_box box;
- unsigned usage = PIPE_TRANSFER_WRITE;
-
- if (offset == 0 && size == buf->width0) {
- usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
- } else {
- usage |= PIPE_TRANSFER_DISCARD_RANGE;
- }
-
- u_box_1d(offset, size, &box);
-
- pipe->transfer_inline_write( pipe,
- buf,
- 0,
- usage,
- &box,
- data,
- size,
- 0);
-}
-
-/**
- * Special case for writing non-overlapping ranges.
- *
- * We can avoid GPU/CPU synchronization when writing range that has never
- * been written before.
- */
-static INLINE void
-pipe_buffer_write_nooverlap(struct pipe_context *pipe,
- struct pipe_resource *buf,
- unsigned offset, unsigned size,
- const void *data)
-{
- struct pipe_box box;
-
- u_box_1d(offset, size, &box);
-
- pipe->transfer_inline_write(pipe,
- buf,
- 0,
- (PIPE_TRANSFER_WRITE |
- PIPE_TRANSFER_NOOVERWRITE),
- &box,
- data,
- 0, 0);
-}
-
-static INLINE void
-pipe_buffer_read(struct pipe_context *pipe,
- struct pipe_resource *buf,
- unsigned offset,
- unsigned size,
- void *data)
-{
- struct pipe_transfer *src_transfer;
- ubyte *map;
-
- map = (ubyte *) pipe_buffer_map_range(pipe,
- buf,
- offset, size,
- PIPE_TRANSFER_READ,
- &src_transfer);
-
- if (map)
- memcpy(data, map + offset, size);
-
- pipe_buffer_unmap(pipe, src_transfer);
-}
-
-static INLINE struct pipe_transfer *
-pipe_get_transfer( struct pipe_context *context,
- struct pipe_resource *resource,
- unsigned level, unsigned layer,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y,
- unsigned w, unsigned h)
-{
- struct pipe_box box;
- u_box_2d_zslice( x, y, layer, w, h, &box );
- return context->get_transfer( context,
- resource,
- level,
- usage,
- &box );
-}
-
-static INLINE void *
-pipe_transfer_map( struct pipe_context *context,
- struct pipe_transfer *transfer )
-{
- return context->transfer_map( context, transfer );
-}
-
-static INLINE void
-pipe_transfer_unmap( struct pipe_context *context,
- struct pipe_transfer *transfer )
-{
- context->transfer_unmap( context, transfer );
-}
-
-
-static INLINE void
-pipe_transfer_destroy( struct pipe_context *context,
- struct pipe_transfer *transfer )
-{
- context->transfer_destroy(context, transfer);
-}
-
-
-static INLINE boolean util_get_offset(
- const struct pipe_rasterizer_state *templ,
- unsigned fill_mode)
-{
- switch(fill_mode) {
- case PIPE_POLYGON_MODE_POINT:
- return templ->offset_point;
- case PIPE_POLYGON_MODE_LINE:
- return templ->offset_line;
- case PIPE_POLYGON_MODE_FILL:
- return templ->offset_tri;
- default:
- assert(0);
- return FALSE;
- }
-}
-
-/**
- * This function is used to copy an array of pipe_vertex_buffer structures,
- * while properly referencing the pipe_vertex_buffer::buffer member.
- *
- * \sa util_copy_framebuffer_state
- */
-static INLINE void util_copy_vertex_buffers(struct pipe_vertex_buffer *dst,
- unsigned *dst_count,
- const struct pipe_vertex_buffer *src,
- unsigned src_count)
-{
- unsigned i;
-
- /* Reference the buffers of 'src' in 'dst'. */
- for (i = 0; i < src_count; i++) {
- pipe_resource_reference(&dst[i].buffer, src[i].buffer);
- }
- /* Unreference the rest of the buffers in 'dst'. */
- for (; i < *dst_count; i++) {
- pipe_resource_reference(&dst[i].buffer, NULL);
- }
-
- /* Update the size of 'dst' and copy over the other members
- * of pipe_vertex_buffer. */
- *dst_count = src_count;
- memcpy(dst, src, src_count * sizeof(struct pipe_vertex_buffer));
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* U_INLINES_H */
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+#ifndef U_INLINES_H
+#define U_INLINES_H
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "pipe/p_screen.h"
+#include "util/u_debug.h"
+#include "util/u_debug_describe.h"
+#include "util/u_debug_refcnt.h"
+#include "util/u_atomic.h"
+#include "util/u_box.h"
+#include "util/u_math.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Reference counting helper functions.
+ */
+
+
+static INLINE void
+pipe_reference_init(struct pipe_reference *reference, unsigned count)
+{
+ p_atomic_set(&reference->count, count);
+}
+
+static INLINE boolean
+pipe_is_referenced(struct pipe_reference *reference)
+{
+ return p_atomic_read(&reference->count) != 0;
+}
+
+/**
+ * Update reference counting.
+ * The old thing pointed to, if any, will be unreferenced.
+ * Both 'ptr' and 'reference' may be NULL.
+ * \return TRUE if the object's refcount hits zero and should be destroyed.
+ */
+static INLINE boolean
+pipe_reference_described(struct pipe_reference *ptr,
+ struct pipe_reference *reference,
+ debug_reference_descriptor get_desc)
+{
+ boolean destroy = FALSE;
+
+ if(ptr != reference) {
+ /* bump the reference.count first */
+ if (reference) {
+ assert(pipe_is_referenced(reference));
+ p_atomic_inc(&reference->count);
+ debug_reference(reference, get_desc, 1);
+ }
+
+ if (ptr) {
+ assert(pipe_is_referenced(ptr));
+ if (p_atomic_dec_zero(&ptr->count)) {
+ destroy = TRUE;
+ }
+ debug_reference(ptr, get_desc, -1);
+ }
+ }
+
+ return destroy;
+}
+
+static INLINE boolean
+pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
+{
+ return pipe_reference_described(ptr, reference,
+ (debug_reference_descriptor)debug_describe_reference);
+}
+
+static INLINE void
+pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
+{
+ struct pipe_surface *old_surf = *ptr;
+
+ if (pipe_reference_described(&(*ptr)->reference, &surf->reference,
+ (debug_reference_descriptor)debug_describe_surface))
+ old_surf->context->surface_destroy(old_surf->context, old_surf);
+ *ptr = surf;
+}
+
+static INLINE void
+pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex)
+{
+ struct pipe_resource *old_tex = *ptr;
+
+ if (pipe_reference_described(&(*ptr)->reference, &tex->reference,
+ (debug_reference_descriptor)debug_describe_resource))
+ old_tex->screen->resource_destroy(old_tex->screen, old_tex);
+ *ptr = tex;
+}
+
+static INLINE void
+pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view)
+{
+ struct pipe_sampler_view *old_view = *ptr;
+
+ if (pipe_reference_described(&(*ptr)->reference, &view->reference,
+ (debug_reference_descriptor)debug_describe_sampler_view))
+ old_view->context->sampler_view_destroy(old_view->context, old_view);
+ *ptr = view;
+}
+
+static INLINE void
+pipe_so_target_reference(struct pipe_stream_output_target **ptr,
+ struct pipe_stream_output_target *target)
+{
+ struct pipe_stream_output_target *old = *ptr;
+
+ if (pipe_reference_described(&(*ptr)->reference, &target->reference,
+ (debug_reference_descriptor)debug_describe_so_target))
+ old->context->stream_output_target_destroy(old->context, old);
+ *ptr = target;
+}
+
+static INLINE void
+pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps,
+ struct pipe_resource *pt, unsigned level, unsigned layer,
+ unsigned flags)
+{
+ pipe_resource_reference(&ps->texture, pt);
+ ps->format = pt->format;
+ ps->width = u_minify(pt->width0, level);
+ ps->height = u_minify(pt->height0, level);
+ ps->usage = flags;
+ ps->u.tex.level = level;
+ ps->u.tex.first_layer = ps->u.tex.last_layer = layer;
+ ps->context = ctx;
+}
+
+static INLINE void
+pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps,
+ struct pipe_resource *pt, unsigned level, unsigned layer,
+ unsigned flags)
+{
+ ps->texture = 0;
+ pipe_reference_init(&ps->reference, 1);
+ pipe_surface_reset(ctx, ps, pt, level, layer, flags);
+}
+
+/* Return true if the surfaces are equal. */
+static INLINE boolean
+pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2)
+{
+ return s1->texture == s2->texture &&
+ s1->format == s2->format &&
+ (s1->texture->target != PIPE_BUFFER ||
+ (s1->u.buf.first_element == s2->u.buf.first_element &&
+ s1->u.buf.last_element == s2->u.buf.last_element)) &&
+ (s1->texture->target == PIPE_BUFFER ||
+ (s1->u.tex.level == s2->u.tex.level &&
+ s1->u.tex.first_layer == s2->u.tex.first_layer &&
+ s1->u.tex.last_layer == s2->u.tex.last_layer));
+}
+
+/*
+ * Convenience wrappers for screen buffer functions.
+ */
+
+static INLINE struct pipe_resource *
+pipe_buffer_create( struct pipe_screen *screen,
+ unsigned bind,
+ unsigned usage,
+ unsigned size )
+{
+ struct pipe_resource buffer;
+ memset(&buffer, 0, sizeof buffer);
+ buffer.target = PIPE_BUFFER;
+ buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
+ buffer.bind = bind;
+ buffer.usage = usage;
+ buffer.flags = 0;
+ buffer.width0 = size;
+ buffer.height0 = 1;
+ buffer.depth0 = 1;
+ buffer.array_size = 1;
+ return screen->resource_create(screen, &buffer);
+}
+
+
+static INLINE struct pipe_resource *
+pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size,
+ unsigned usage )
+{
+ return screen->user_buffer_create(screen, ptr, size, usage);
+}
+
+static INLINE void *
+pipe_buffer_map_range(struct pipe_context *pipe,
+ struct pipe_resource *buffer,
+ unsigned offset,
+ unsigned length,
+ unsigned usage,
+ struct pipe_transfer **transfer)
+{
+ struct pipe_box box;
+ void *map;
+
+ assert(offset < buffer->width0);
+ assert(offset + length <= buffer->width0);
+ assert(length);
+
+ u_box_1d(offset, length, &box);
+
+ *transfer = pipe->get_transfer( pipe,
+ buffer,
+ 0,
+ usage,
+ &box);
+
+ if (*transfer == NULL)
+ return NULL;
+
+ map = pipe->transfer_map( pipe, *transfer );
+ if (map == NULL) {
+ pipe->transfer_destroy( pipe, *transfer );
+ *transfer = NULL;
+ return NULL;
+ }
+
+ /* Match old screen->buffer_map_range() behaviour, return pointer
+ * to where the beginning of the buffer would be:
+ */
+ return (void *)((char *)map - offset);
+}
+
+
+static INLINE void *
+pipe_buffer_map(struct pipe_context *pipe,
+ struct pipe_resource *buffer,
+ unsigned usage,
+ struct pipe_transfer **transfer)
+{
+ return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer);
+}
+
+
+static INLINE void
+pipe_buffer_unmap(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
+{
+ if (transfer) {
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->transfer_destroy(pipe, transfer);
+ }
+}
+
+static INLINE void
+pipe_buffer_flush_mapped_range(struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ unsigned offset,
+ unsigned length)
+{
+ struct pipe_box box;
+ int transfer_offset;
+
+ assert(length);
+ assert(transfer->box.x <= offset);
+ assert(offset + length <= transfer->box.x + transfer->box.width);
+
+ /* Match old screen->buffer_flush_mapped_range() behaviour, where
+ * offset parameter is relative to the start of the buffer, not the
+ * mapped range.
+ */
+ transfer_offset = offset - transfer->box.x;
+
+ u_box_1d(transfer_offset, length, &box);
+
+ pipe->transfer_flush_region(pipe, transfer, &box);
+}
+
+static INLINE void
+pipe_buffer_write(struct pipe_context *pipe,
+ struct pipe_resource *buf,
+ unsigned offset,
+ unsigned size,
+ const void *data)
+{
+ struct pipe_box box;
+ unsigned usage = PIPE_TRANSFER_WRITE;
+
+ if (offset == 0 && size == buf->width0) {
+ usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
+ } else {
+ usage |= PIPE_TRANSFER_DISCARD_RANGE;
+ }
+
+ u_box_1d(offset, size, &box);
+
+ pipe->transfer_inline_write( pipe,
+ buf,
+ 0,
+ usage,
+ &box,
+ data,
+ size,
+ 0);
+}
+
+/**
+ * Special case for writing non-overlapping ranges.
+ *
+ * We can avoid GPU/CPU synchronization when writing range that has never
+ * been written before.
+ */
+static INLINE void
+pipe_buffer_write_nooverlap(struct pipe_context *pipe,
+ struct pipe_resource *buf,
+ unsigned offset, unsigned size,
+ const void *data)
+{
+ struct pipe_box box;
+
+ u_box_1d(offset, size, &box);
+
+ pipe->transfer_inline_write(pipe,
+ buf,
+ 0,
+ (PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_NOOVERWRITE),
+ &box,
+ data,
+ 0, 0);
+}
+
+static INLINE void
+pipe_buffer_read(struct pipe_context *pipe,
+ struct pipe_resource *buf,
+ unsigned offset,
+ unsigned size,
+ void *data)
+{
+ struct pipe_transfer *src_transfer;
+ ubyte *map;
+
+ map = (ubyte *) pipe_buffer_map_range(pipe,
+ buf,
+ offset, size,
+ PIPE_TRANSFER_READ,
+ &src_transfer);
+
+ if (map)
+ memcpy(data, map + offset, size);
+
+ pipe_buffer_unmap(pipe, src_transfer);
+}
+
+static INLINE struct pipe_transfer *
+pipe_get_transfer( struct pipe_context *context,
+ struct pipe_resource *resource,
+ unsigned level, unsigned layer,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y,
+ unsigned w, unsigned h)
+{
+ struct pipe_box box;
+ u_box_2d_zslice( x, y, layer, w, h, &box );
+ return context->get_transfer( context,
+ resource,
+ level,
+ usage,
+ &box );
+}
+
+static INLINE void *
+pipe_transfer_map( struct pipe_context *context,
+ struct pipe_transfer *transfer )
+{
+ return context->transfer_map( context, transfer );
+}
+
+static INLINE void
+pipe_transfer_unmap( struct pipe_context *context,
+ struct pipe_transfer *transfer )
+{
+ context->transfer_unmap( context, transfer );
+}
+
+
+static INLINE void
+pipe_transfer_destroy( struct pipe_context *context,
+ struct pipe_transfer *transfer )
+{
+ context->transfer_destroy(context, transfer);
+}
+
+
+static INLINE boolean util_get_offset(
+ const struct pipe_rasterizer_state *templ,
+ unsigned fill_mode)
+{
+ switch(fill_mode) {
+ case PIPE_POLYGON_MODE_POINT:
+ return templ->offset_point;
+ case PIPE_POLYGON_MODE_LINE:
+ return templ->offset_line;
+ case PIPE_POLYGON_MODE_FILL:
+ return templ->offset_tri;
+ default:
+ assert(0);
+ return FALSE;
+ }
+}
+
+/**
+ * This function is used to copy an array of pipe_vertex_buffer structures,
+ * while properly referencing the pipe_vertex_buffer::buffer member.
+ *
+ * \sa util_copy_framebuffer_state
+ */
+static INLINE void util_copy_vertex_buffers(struct pipe_vertex_buffer *dst,
+ unsigned *dst_count,
+ const struct pipe_vertex_buffer *src,
+ unsigned src_count)
+{
+ unsigned i;
+
+ /* Reference the buffers of 'src' in 'dst'. */
+ for (i = 0; i < src_count; i++) {
+ pipe_resource_reference(&dst[i].buffer, src[i].buffer);
+ }
+ /* Unreference the rest of the buffers in 'dst'. */
+ for (; i < *dst_count; i++) {
+ pipe_resource_reference(&dst[i].buffer, NULL);
+ }
+
+ /* Update the size of 'dst' and copy over the other members
+ * of pipe_vertex_buffer. */
+ *dst_count = src_count;
+ memcpy(dst, src, src_count * sizeof(struct pipe_vertex_buffer));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* U_INLINES_H */
diff --git a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c
index 141763190..320c0f7a8 100644
--- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -1,243 +1,255 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * Copyright 2009 Marek Olšák <maraeo@gmail.com>
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-/**
- * @file
- * Simple vertex/fragment shader generators.
- *
- * @author Brian Paul
- Marek Olšák
- */
-
-
-#include "pipe/p_context.h"
-#include "pipe/p_shader_tokens.h"
-#include "pipe/p_state.h"
-#include "util/u_simple_shaders.h"
-#include "util/u_debug.h"
-#include "tgsi/tgsi_ureg.h"
-
-
-
-/**
- * Make simple vertex pass-through shader.
- * \param num_attribs number of attributes to pass through
- * \param semantic_names array of semantic names for each attribute
- * \param semantic_indexes array of semantic indexes for each attribute
- */
-void *
-util_make_vertex_passthrough_shader(struct pipe_context *pipe,
- uint num_attribs,
- const uint *semantic_names,
- const uint *semantic_indexes)
-{
- struct ureg_program *ureg;
- uint i;
-
- ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
- if (ureg == NULL)
- return NULL;
-
- for (i = 0; i < num_attribs; i++) {
- struct ureg_src src;
- struct ureg_dst dst;
-
- src = ureg_DECL_vs_input( ureg, i );
-
- dst = ureg_DECL_output( ureg,
- semantic_names[i],
- semantic_indexes[i]);
-
- ureg_MOV( ureg, dst, src );
- }
-
- ureg_END( ureg );
-
- return ureg_create_shader_and_destroy( ureg, pipe );
-}
-
-
-/**
- * Make simple fragment texture shader:
- * IMM {0,0,0,1} // (if writemask != 0xf)
- * MOV OUT[0], IMM[0] // (if writemask != 0xf)
- * TEX OUT[0].writemask, IN[0], SAMP[0], 2D;
- * END;
- *
- * \param tex_target one of PIPE_TEXTURE_x
- * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE
- * \param writemask mask of TGSI_WRITEMASK_x
- */
-void *
-util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
- unsigned tex_target,
- unsigned interp_mode,
- unsigned writemask )
-{
- struct ureg_program *ureg;
- struct ureg_src sampler;
- struct ureg_src tex;
- struct ureg_dst out;
-
- assert(interp_mode == TGSI_INTERPOLATE_LINEAR ||
- interp_mode == TGSI_INTERPOLATE_PERSPECTIVE);
-
- ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
- return NULL;
-
- sampler = ureg_DECL_sampler( ureg, 0 );
-
- tex = ureg_DECL_fs_input( ureg,
- TGSI_SEMANTIC_GENERIC, 0,
- interp_mode );
-
- out = ureg_DECL_output( ureg,
- TGSI_SEMANTIC_COLOR,
- 0 );
-
- if (writemask != TGSI_WRITEMASK_XYZW) {
- struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
-
- ureg_MOV( ureg, out, imm );
- }
-
- ureg_TEX( ureg,
- ureg_writemask(out, writemask),
- tex_target, tex, sampler );
- ureg_END( ureg );
-
- return ureg_create_shader_and_destroy( ureg, pipe );
-}
-
-
-/**
- * Make a simple fragment shader that sets the output color to a color
- * taken from a texture.
- * \param tex_target one of PIPE_TEXTURE_x
- */
-void *
-util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
- unsigned interp_mode)
-{
- return util_make_fragment_tex_shader_writemask( pipe,
- tex_target,
- interp_mode,
- TGSI_WRITEMASK_XYZW );
-}
-
-
-/**
- * Make a simple fragment texture shader which reads an X component from
- * a texture and writes it as depth.
- */
-void *
-util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
- unsigned tex_target,
- unsigned interp_mode)
-{
- struct ureg_program *ureg;
- struct ureg_src sampler;
- struct ureg_src tex;
- struct ureg_dst out, depth;
- struct ureg_src imm;
-
- ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
- return NULL;
-
- sampler = ureg_DECL_sampler( ureg, 0 );
-
- tex = ureg_DECL_fs_input( ureg,
- TGSI_SEMANTIC_GENERIC, 0,
- interp_mode );
-
- out = ureg_DECL_output( ureg,
- TGSI_SEMANTIC_COLOR,
- 0 );
-
- depth = ureg_DECL_output( ureg,
- TGSI_SEMANTIC_POSITION,
- 0 );
-
- imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
-
- ureg_MOV( ureg, out, imm );
-
- ureg_TEX( ureg,
- ureg_writemask(depth, TGSI_WRITEMASK_Z),
- tex_target, tex, sampler );
- ureg_END( ureg );
-
- return ureg_create_shader_and_destroy( ureg, pipe );
-}
-
-
-/**
- * Make simple fragment color pass-through shader.
- */
-void *
-util_make_fragment_passthrough_shader(struct pipe_context *pipe)
-{
- return util_make_fragment_cloneinput_shader(pipe, 1, TGSI_SEMANTIC_COLOR,
- TGSI_INTERPOLATE_PERSPECTIVE);
-}
-
-
-/**
- * Make a fragment shader that copies the input color to N output colors.
- */
-void *
-util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
- int input_semantic,
- int input_interpolate)
-{
- struct ureg_program *ureg;
- struct ureg_src src;
- struct ureg_dst dst[PIPE_MAX_COLOR_BUFS];
- int i;
-
- assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
-
- ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
- return NULL;
-
- src = ureg_DECL_fs_input( ureg, input_semantic, 0,
- input_interpolate );
-
- for (i = 0; i < num_cbufs; i++)
- dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i );
-
- for (i = 0; i < num_cbufs; i++)
- ureg_MOV( ureg, dst[i], src );
-
- ureg_END( ureg );
-
- return ureg_create_shader_and_destroy( ureg, pipe );
-}
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Simple vertex/fragment shader generators.
+ *
+ * @author Brian Paul
+ Marek Olšák
+ */
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_shader_tokens.h"
+#include "pipe/p_state.h"
+#include "util/u_simple_shaders.h"
+#include "util/u_debug.h"
+#include "tgsi/tgsi_ureg.h"
+
+
+
+/**
+ * Make simple vertex pass-through shader.
+ * \param num_attribs number of attributes to pass through
+ * \param semantic_names array of semantic names for each attribute
+ * \param semantic_indexes array of semantic indexes for each attribute
+ */
+void *
+util_make_vertex_passthrough_shader(struct pipe_context *pipe,
+ uint num_attribs,
+ const uint *semantic_names,
+ const uint *semantic_indexes)
+{
+ return util_make_vertex_passthrough_shader_with_so(pipe, num_attribs,
+ semantic_names,
+ semantic_indexes, NULL);
+}
+
+void *
+util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe,
+ uint num_attribs,
+ const uint *semantic_names,
+ const uint *semantic_indexes,
+ const struct pipe_stream_output_info *so)
+{
+ struct ureg_program *ureg;
+ uint i;
+
+ ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+ if (ureg == NULL)
+ return NULL;
+
+ for (i = 0; i < num_attribs; i++) {
+ struct ureg_src src;
+ struct ureg_dst dst;
+
+ src = ureg_DECL_vs_input( ureg, i );
+
+ dst = ureg_DECL_output( ureg,
+ semantic_names[i],
+ semantic_indexes[i]);
+
+ ureg_MOV( ureg, dst, src );
+ }
+
+ ureg_END( ureg );
+
+ return ureg_create_shader_with_so_and_destroy( ureg, pipe, so );
+}
+
+
+/**
+ * Make simple fragment texture shader:
+ * IMM {0,0,0,1} // (if writemask != 0xf)
+ * MOV OUT[0], IMM[0] // (if writemask != 0xf)
+ * TEX OUT[0].writemask, IN[0], SAMP[0], 2D;
+ * END;
+ *
+ * \param tex_target one of PIPE_TEXTURE_x
+ * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE
+ * \param writemask mask of TGSI_WRITEMASK_x
+ */
+void *
+util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
+ unsigned tex_target,
+ unsigned interp_mode,
+ unsigned writemask )
+{
+ struct ureg_program *ureg;
+ struct ureg_src sampler;
+ struct ureg_src tex;
+ struct ureg_dst out;
+
+ assert(interp_mode == TGSI_INTERPOLATE_LINEAR ||
+ interp_mode == TGSI_INTERPOLATE_PERSPECTIVE);
+
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ sampler = ureg_DECL_sampler( ureg, 0 );
+
+ tex = ureg_DECL_fs_input( ureg,
+ TGSI_SEMANTIC_GENERIC, 0,
+ interp_mode );
+
+ out = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0 );
+
+ if (writemask != TGSI_WRITEMASK_XYZW) {
+ struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
+
+ ureg_MOV( ureg, out, imm );
+ }
+
+ ureg_TEX( ureg,
+ ureg_writemask(out, writemask),
+ tex_target, tex, sampler );
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg, pipe );
+}
+
+
+/**
+ * Make a simple fragment shader that sets the output color to a color
+ * taken from a texture.
+ * \param tex_target one of PIPE_TEXTURE_x
+ */
+void *
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
+ unsigned interp_mode)
+{
+ return util_make_fragment_tex_shader_writemask( pipe,
+ tex_target,
+ interp_mode,
+ TGSI_WRITEMASK_XYZW );
+}
+
+
+/**
+ * Make a simple fragment texture shader which reads an X component from
+ * a texture and writes it as depth.
+ */
+void *
+util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
+ unsigned tex_target,
+ unsigned interp_mode)
+{
+ struct ureg_program *ureg;
+ struct ureg_src sampler;
+ struct ureg_src tex;
+ struct ureg_dst out, depth;
+ struct ureg_src imm;
+
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ sampler = ureg_DECL_sampler( ureg, 0 );
+
+ tex = ureg_DECL_fs_input( ureg,
+ TGSI_SEMANTIC_GENERIC, 0,
+ interp_mode );
+
+ out = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0 );
+
+ depth = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_POSITION,
+ 0 );
+
+ imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
+
+ ureg_MOV( ureg, out, imm );
+
+ ureg_TEX( ureg,
+ ureg_writemask(depth, TGSI_WRITEMASK_Z),
+ tex_target, tex, sampler );
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg, pipe );
+}
+
+
+/**
+ * Make simple fragment color pass-through shader.
+ */
+void *
+util_make_fragment_passthrough_shader(struct pipe_context *pipe)
+{
+ return util_make_fragment_cloneinput_shader(pipe, 1, TGSI_SEMANTIC_COLOR,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+}
+
+
+/**
+ * Make a fragment shader that copies the input color to N output colors.
+ */
+void *
+util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
+ int input_semantic,
+ int input_interpolate)
+{
+ struct ureg_program *ureg;
+ struct ureg_src src;
+ struct ureg_dst dst[PIPE_MAX_COLOR_BUFS];
+ int i;
+
+ assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
+
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ src = ureg_DECL_fs_input( ureg, input_semantic, 0,
+ input_interpolate );
+
+ for (i = 0; i < num_cbufs; i++)
+ dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i );
+
+ for (i = 0; i < num_cbufs; i++)
+ ureg_MOV( ureg, dst[i], src );
+
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg, pipe );
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h
index 9a0fe6375..5f31b72c4 100644
--- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -1,83 +1,91 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-
-#ifndef U_SIMPLE_SHADERS_H
-#define U_SIMPLE_SHADERS_H
-
-
-#include "pipe/p_compiler.h"
-
-
-struct pipe_context;
-struct pipe_shader_state;
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-extern void *
-util_make_vertex_passthrough_shader(struct pipe_context *pipe,
- uint num_attribs,
- const uint *semantic_names,
- const uint *semantic_indexes);
-
-
-extern void *
-util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
- unsigned tex_target,
- unsigned interp_mode,
- unsigned writemask);
-
-extern void *
-util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
- unsigned interp_mode);
-
-
-extern void *
-util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
- unsigned tex_target,
- unsigned interp_mode);
-
-
-extern void *
-util_make_fragment_passthrough_shader(struct pipe_context *pipe);
-
-
-extern void *
-util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
- int input_semantic,
- int input_interpolate);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+
+#ifndef U_SIMPLE_SHADERS_H
+#define U_SIMPLE_SHADERS_H
+
+
+#include "pipe/p_compiler.h"
+
+
+struct pipe_context;
+struct pipe_shader_state;
+struct pipe_stream_output_info;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern void *
+util_make_vertex_passthrough_shader(struct pipe_context *pipe,
+ uint num_attribs,
+ const uint *semantic_names,
+ const uint *semantic_indexes);
+
+extern void *
+util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe,
+ uint num_attribs,
+ const uint *semantic_names,
+ const uint *semantic_indexes,
+ const struct pipe_stream_output_info *so);
+
+
+extern void *
+util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
+ unsigned tex_target,
+ unsigned interp_mode,
+ unsigned writemask);
+
+extern void *
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
+ unsigned interp_mode);
+
+
+extern void *
+util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
+ unsigned tex_target,
+ unsigned interp_mode);
+
+
+extern void *
+util_make_fragment_passthrough_shader(struct pipe_context *pipe);
+
+
+extern void *
+util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs,
+ int input_semantic,
+ int input_interpolate);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index 259041f67..1683c85e9 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -2943,43 +2943,20 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
break;
}
- /* Set MaxLevel large enough to hold the new level when we allocate it */
+ /* Allocate storage for the destination mipmap image(s) */
+
+ /* Set MaxLevel large enough to hold the new level when we allocate it */
_mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
- /* Create empty dest image */
- if (target == GL_TEXTURE_1D) {
- _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat,
- dstWidth, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- else if (target == GL_TEXTURE_3D) {
- _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat,
- dstWidth, dstHeight, dstDepth, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- else {
- /* 2D or cube */
- _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat,
- dstWidth, dstHeight, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- if (target == GL_TEXTURE_CUBE_MAP) {
- /* If texturing from a cube, we need to make sure all src faces
- * have been defined (even if we're not sampling from them.)
- * Otherwise the texture object will be 'incomplete' and
- * texturing from it will not be allowed.
- */
- GLuint face;
- for (face = 0; face < 6; face++) {
- if (!texObj->Image[face][srcLevel] ||
- texObj->Image[face][srcLevel]->Width != srcWidth) {
- _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
- srcLevel, srcImage->InternalFormat,
- srcWidth, srcHeight, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
- }
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel,
+ dstWidth, dstHeight, dstDepth,
+ srcImage->Border,
+ srcImage->InternalFormat,
+ srcImage->TexFormat)) {
+ /* All done. We either ran out of memory or we would go beyond the
+ * last valid level of an immutable texture if we continued.
+ */
+ break;
}
/* limit minification to src level */
diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c
index efdecb212..945f12752 100644
--- a/mesalib/src/mesa/main/api_validate.c
+++ b/mesalib/src/mesa/main/api_validate.c
@@ -474,3 +474,37 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
return GL_TRUE;
}
+
+
+#if FEATURE_EXT_transform_feedback
+
+GLboolean
+_mesa_validate_DrawTransformFeedback(struct gl_context *ctx,
+ GLenum mode,
+ struct gl_transform_feedback_object *obj)
+{
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (!_mesa_valid_prim_mode(ctx, mode)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawTransformFeedback(mode)");
+ return GL_FALSE;
+ }
+
+ if (!obj) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback(name)");
+ return GL_FALSE;
+ }
+
+ if (!obj->EndedAnytime) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback");
+ return GL_FALSE;
+ }
+
+ if (!check_valid_to_render(ctx, "glDrawTransformFeedback")) {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+#endif
diff --git a/mesalib/src/mesa/main/api_validate.h b/mesalib/src/mesa/main/api_validate.h
index 7d6a66012..f4948424c 100644
--- a/mesalib/src/mesa/main/api_validate.h
+++ b/mesalib/src/mesa/main/api_validate.h
@@ -29,9 +29,11 @@
#include "glheader.h"
+#include "mfeatures.h"
struct gl_buffer_object;
struct gl_context;
+struct gl_transform_feedback_object;
extern GLuint
@@ -70,5 +72,13 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
const GLvoid *indices, GLsizei primcount,
GLint basevertex);
+#if FEATURE_EXT_transform_feedback
+
+extern GLboolean
+_mesa_validate_DrawTransformFeedback(struct gl_context *ctx,
+ GLenum mode,
+ struct gl_transform_feedback_object *obj);
+
+#endif
#endif
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index d6f70d1c4..01cfff8ab 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -964,8 +964,6 @@ struct dd_function_table {
struct gl_transform_feedback_object *obj);
void (*ResumeTransformFeedback)(struct gl_context *ctx,
struct gl_transform_feedback_object *obj);
- void (*DrawTransformFeedback)(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj);
/**
* \name GL_NV_texture_barrier interface
@@ -1194,6 +1192,7 @@ typedef struct {
void (GLAPIENTRYP DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count,
GLenum type, const GLvoid *indices,
GLsizei primcount, GLint basevertex);
+ void (GLAPIENTRYP DrawTransformFeedback)(GLenum mode, GLuint name);
/*@}*/
/**
diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c
index e1acc8028..b3edae0e6 100644
--- a/mesalib/src/mesa/main/dlist.c
+++ b/mesalib/src/mesa/main/dlist.c
@@ -1422,7 +1422,7 @@ save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));
}
}
@@ -1450,7 +1450,7 @@ save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));
}
}
@@ -1478,7 +1478,7 @@ save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));
}
}
@@ -1498,7 +1498,7 @@ save_ClearBufferfi(GLenum buffer, GLint drawbuffer,
n[4].i = stencil;
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));*/
+ CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));
}
}
@@ -7545,36 +7545,36 @@ execute_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_CLEAR_BUFFER_IV:
{
- /*GLint value[4];
+ GLint value[4];
value[0] = n[3].i;
value[1] = n[4].i;
value[2] = n[5].i;
value[3] = n[6].i;
- CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_UIV:
{
- /*GLuint value[4];
+ GLuint value[4];
value[0] = n[3].ui;
value[1] = n[4].ui;
value[2] = n[5].ui;
value[3] = n[6].ui;
- CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferuiv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_FV:
{
- /*GLfloat value[4];
+ GLfloat value[4];
value[0] = n[3].f;
value[1] = n[4].f;
value[2] = n[5].f;
value[3] = n[6].f;
- CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_FI:
- /*CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));*/
+ CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));
break;
case OPCODE_CLEAR_COLOR:
CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 611a6d0b0..912170aba 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -819,7 +819,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
fbo_incomplete("width or height mismatch", -1);
return;
}
- /* check that all color buffer have same format */
+ /* check that all color buffers are the same format */
if (intFormat != GL_NONE && f != intFormat) {
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
fbo_incomplete("format mismatch", -1);
@@ -831,8 +831,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
fbo_incomplete("inconsistant number of samples", i);
return;
- }
-
+ }
}
}
@@ -1273,7 +1272,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
case GL_RG32I:
return ctx->Extensions.ARB_texture_rg &&
ctx->Extensions.EXT_texture_integer ? GL_RG : 0;
-
+
case GL_INTENSITY8I_EXT:
case GL_INTENSITY8UI_EXT:
case GL_INTENSITY16I_EXT:
@@ -1820,7 +1819,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
/* bind default */
ASSERT(fb->RefCount >= 2);
_mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
+ }
}
/* remove from hash table immediately, to free the ID */
@@ -1897,6 +1896,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
return buffer->_Status;
}
+
/**
* Replicate the src attachment point. Used by framebuffer_texture() when
* the same texture is attached at GL_DEPTH_ATTACHMENT and
@@ -1911,7 +1911,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *src_att = &fb->Attachment[src];
assert(src_att->Texture != NULL);
- assert (src_att->Renderbuffer != NULL);
+ assert(src_att->Renderbuffer != NULL);
_mesa_reference_texobj(&dst_att->Texture, src_att->Texture);
_mesa_reference_renderbuffer(&dst_att->Renderbuffer, src_att->Renderbuffer);
@@ -1921,6 +1921,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
dst_att->Zoffset = src_att->Zoffset;
}
+
/**
* Common code called by glFramebufferTexture1D/2D/3DEXT().
*/
@@ -1949,7 +1950,6 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
return;
}
-
/* The textarget, level, and zoffset parameters are only validated if
* texture is non-zero.
*/
@@ -2002,7 +2002,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
}
- if ((level < 0) ||
+ if ((level < 0) ||
(level >= _mesa_max_texture_levels(ctx, texObj->Target))) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glFramebufferTexture%sEXT(level)", caller);
@@ -2031,7 +2031,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH,
BUFFER_STENCIL);
} else if (attachment == GL_STENCIL_ATTACHMENT &&
- texObj== fb->Attachment[BUFFER_DEPTH].Texture) {
+ texObj == fb->Attachment[BUFFER_DEPTH].Texture) {
/* As above, but with depth and stencil juxtasposed. */
reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
BUFFER_DEPTH);
@@ -2797,6 +2797,7 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
#endif /* FEATURE_EXT_framebuffer_blit */
+
#if FEATURE_ARB_geometry_shader4
void GLAPIENTRY
_mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
@@ -2808,6 +2809,7 @@ _mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
"not implemented!");
}
+
void GLAPIENTRY
_mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLenum face)
diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c
index 4f23f3dec..32d198ce8 100644
--- a/mesalib/src/mesa/main/format_unpack.c
+++ b/mesalib/src/mesa/main/format_unpack.c
@@ -1822,6 +1822,10 @@ unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst)
+/**
+ * Unpack Z values.
+ * The returned values will always be in the range [0.0, 1.0].
+ */
void
_mesa_unpack_float_z_row(gl_format format, GLuint n,
const void *src, GLfloat *dst)
@@ -1901,6 +1905,10 @@ unpack_uint_z_Z32(const void *src, GLuint *dst, GLuint n)
}
+/**
+ * Unpack Z values.
+ * The returned values will always be in the range [0, 0xffffffff].
+ */
void
_mesa_unpack_uint_z_row(gl_format format, GLuint n,
const void *src, GLuint *dst)
diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c
index fd6e582ec..867cb22e2 100644
--- a/mesalib/src/mesa/main/mipmap.c
+++ b/mesalib/src/mesa/main/mipmap.c
@@ -1803,6 +1803,81 @@ next_mipmap_level_size(GLenum target, GLint border,
}
}
+
+/**
+ * Helper function for mipmap generation.
+ * Make sure the specified destination mipmap level is the right size/format
+ * for mipmap generation. If not, (re) allocate it.
+ * \return GL_TRUE if successful, GL_FALSE if mipmap generation should stop
+ */
+GLboolean
+_mesa_prepare_mipmap_level(struct gl_context *ctx,
+ struct gl_texture_object *texObj, GLuint level,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei border, GLenum intFormat, gl_format format)
+{
+ const GLuint numFaces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+ GLuint face;
+
+ if (texObj->Immutable) {
+ /* The texture was created with glTexStorage() so the number/size of
+ * mipmap levels is fixed and the storage for all images is already
+ * allocated.
+ */
+ if (!texObj->Image[0][level]) {
+ /* No more levels to create - we're done */
+ return GL_FALSE;
+ }
+ else {
+ /* Nothing to do - the texture memory must have already been
+ * allocated to the right size so we're all set.
+ */
+ return GL_TRUE;
+ }
+ }
+
+ for (face = 0; face < numFaces; face++) {
+ struct gl_texture_image *dstImage;
+ GLenum target;
+
+ if (numFaces == 1)
+ target = texObj->Target;
+ else
+ target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+
+ dstImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ if (!dstImage) {
+ /* out of memory */
+ return GL_FALSE;
+ }
+
+ if (dstImage->Width != width ||
+ dstImage->Height != height ||
+ dstImage->Depth != depth ||
+ dstImage->Border != border ||
+ dstImage->InternalFormat != intFormat ||
+ dstImage->TexFormat != format) {
+ /* need to (re)allocate image */
+ ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
+
+ _mesa_init_teximage_fields(ctx, target, dstImage,
+ width, height, depth,
+ border, intFormat, format);
+
+ ctx->Driver.AllocTextureImageBuffer(ctx, dstImage,
+ format, width, height, depth);
+
+ /* in case the mipmap level is part of an FBO: */
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
static void
generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj,
@@ -1841,31 +1916,20 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
if (!nextLevel)
return;
- /* get dest gl_texture_image */
- dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
- if (!dstImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
+ dstWidth, dstHeight, dstDepth,
+ border, srcImage->InternalFormat,
+ srcImage->TexFormat)) {
return;
}
- /* Free old image data */
- ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
-
- _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
- dstDepth, border, srcImage->InternalFormat,
- srcImage->TexFormat);
-
- /* Alloc storage for new texture image */
- if (!ctx->Driver.AllocTextureImageBuffer(ctx, dstImage,
- dstImage->TexFormat,
- dstWidth, dstHeight,
- dstDepth)) {
+ /* get dest gl_texture_image */
+ dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
+ if (!dstImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
return;
}
- ASSERT(dstImage->TexFormat);
-
if (target == GL_TEXTURE_1D_ARRAY) {
srcDepth = srcHeight;
dstDepth = dstHeight;
@@ -2052,9 +2116,7 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
return;
}
- /* Free old image data */
- ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
-
+ /* rescale src image to dest image */
_mesa_generate_mipmap_level(target, temp_datatype, components, border,
srcWidth, srcHeight, srcDepth,
(const GLubyte **) &temp_src,
@@ -2062,19 +2124,19 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
dstWidth, dstHeight, dstDepth,
&temp_dst, temp_dst_stride);
- /* initialize new image */
- _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
- dstDepth, border, srcImage->InternalFormat,
- srcImage->TexFormat);
-
- /* Free old dest texture image buffer */
- ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
+ dstWidth, dstHeight, dstDepth,
+ border, srcImage->InternalFormat,
+ srcImage->TexFormat)) {
+ return;
+ }
- ctx->Driver.TexImage2D(ctx, target, level + 1,
- srcImage->InternalFormat,
- dstWidth, dstHeight, border,
- temp_base_format, temp_datatype,
- temp_dst, &ctx->DefaultPacking, texObj, dstImage);
+ /* The image space was allocated above so use glTexSubImage now */
+ ctx->Driver.TexSubImage2D(ctx, target, level + 1,
+ 0, 0, dstWidth, dstHeight,
+ temp_base_format, temp_datatype,
+ temp_dst, &ctx->DefaultPacking,
+ texObj, dstImage);
/* swap src and dest pointers */
{
diff --git a/mesalib/src/mesa/main/mipmap.h b/mesalib/src/mesa/main/mipmap.h
index 1fb9146a1..072794cb6 100644
--- a/mesalib/src/mesa/main/mipmap.h
+++ b/mesalib/src/mesa/main/mipmap.h
@@ -41,6 +41,12 @@ _mesa_generate_mipmap_level(GLenum target,
GLint dstRowStride);
+extern GLboolean
+_mesa_prepare_mipmap_level(struct gl_context *ctx,
+ struct gl_texture_object *texObj, GLuint level,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei border, GLenum intFormat, gl_format format);
+
extern void
_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj);
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 193434976..0e29dc0dc 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -2355,6 +2355,8 @@ struct gl_transform_feedback_object
GLint RefCount;
GLboolean Active; /**< Is transform feedback enabled? */
GLboolean Paused; /**< Is transform feedback paused? */
+ GLboolean EndedAnytime; /**< Has EndTransformFeedback been called
+ at least once? */
/** The feedback buffers */
GLuint BufferNames[MAX_FEEDBACK_ATTRIBS];
diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c
index c776b4160..7e60541c3 100644
--- a/mesalib/src/mesa/main/texformat.c
+++ b/mesalib/src/mesa/main/texformat.c
@@ -118,6 +118,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
break;
case GL_R3_G3_B2:
RETURN_IF_SUPPORTED(MESA_FORMAT_RGB332);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565_REV);
RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);
RETURN_IF_SUPPORTED(MESA_FORMAT_XRGB8888);
RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index ae0d51fbb..3f2418729 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -708,6 +708,14 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
return GL_TRUE;
}
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ /*GL_INVALID_OPERATION is generated by a format/type
+ * mismatch (see the 1.2 spec page 94, sec 3.6.4.)
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(target)");
+ return GL_TRUE;
+ }
+
baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
/* Make sure the requested image format is compatible with the
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 8a002b675..eccc0fd39 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -2205,9 +2205,10 @@ check_rtt_cb(GLuint key, void *data, void *userData)
* in size or format since that effects FBO completeness.
* Any FBOs rendering into the texture must be re-validated.
*/
-static void
-update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj,
- GLuint face, GLuint level)
+void
+_mesa_update_fbo_texture(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLuint face, GLuint level)
{
/* Only check this texture if it's been marked as RenderToTexture */
if (texObj->_RenderToTexture) {
@@ -2502,7 +2503,7 @@ teximage(struct gl_context *ctx, GLuint dims,
check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
/* state update */
texObj->_Complete = GL_FALSE;
@@ -2844,7 +2845,7 @@ copyteximage(struct gl_context *ctx, GLuint dims,
check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
/* state update */
texObj->_Complete = GL_FALSE;
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 9cc7d5a54..d756646ce 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -80,6 +80,10 @@ _mesa_choose_texture_format(struct gl_context *ctx,
GLenum target, GLint level,
GLenum internalFormat, GLenum format, GLenum type);
+extern void
+_mesa_update_fbo_texture(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLuint face, GLuint level);
extern void
_mesa_clear_texture_image(struct gl_context *ctx,
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index 799245d4e..824f66a35 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -294,18 +294,6 @@ resume_transform_feedback(struct gl_context *ctx,
/* nop */
}
-/** Default fallback for ctx->Driver.DrawTransformFeedback() */
-static void
-draw_transform_feedback(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj)
-{
- /* XXX to do */
- /*
- * Get number of vertices in obj's feedback buffer.
- * Call ctx->Exec.DrawArrays(mode, 0, count);
- */
-}
-
/**
* Plug in default device driver functions for transform feedback.
@@ -320,7 +308,6 @@ _mesa_init_transform_feedback_functions(struct dd_function_table *driver)
driver->EndTransformFeedback = end_transform_feedback;
driver->PauseTransformFeedback = pause_transform_feedback;
driver->ResumeTransformFeedback = resume_transform_feedback;
- driver->DrawTransformFeedback = draw_transform_feedback;
}
@@ -342,7 +329,6 @@ _mesa_init_transform_feedback_dispatch(struct _glapi_table *disp)
SET_IsTransformFeedback(disp, _mesa_IsTransformFeedback);
SET_PauseTransformFeedback(disp, _mesa_PauseTransformFeedback);
SET_ResumeTransformFeedback(disp, _mesa_ResumeTransformFeedback);
- SET_DrawTransformFeedback(disp, _mesa_DrawTransformFeedback);
}
@@ -401,6 +387,7 @@ _mesa_EndTransformFeedback(void)
FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK);
ctx->TransformFeedback.CurrentObject->Active = GL_FALSE;
+ ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE;
assert(ctx->Driver.EndTransformFeedback);
ctx->Driver.EndTransformFeedback(ctx, obj);
@@ -714,8 +701,8 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
-static struct gl_transform_feedback_object *
-lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
+struct gl_transform_feedback_object *
+_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
{
if (name == 0) {
return ctx->TransformFeedback.DefaultObject;
@@ -780,7 +767,7 @@ _mesa_IsTransformFeedback(GLuint name)
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (name && lookup_transform_feedback_object(ctx, name))
+ if (name && _mesa_lookup_transform_feedback_object(ctx, name))
return GL_TRUE;
else
return GL_FALSE;
@@ -809,7 +796,7 @@ _mesa_BindTransformFeedback(GLenum target, GLuint name)
return;
}
- obj = lookup_transform_feedback_object(ctx, name);
+ obj = _mesa_lookup_transform_feedback_object(ctx, name);
if (!obj) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBindTransformFeedback(name=%u)", name);
@@ -844,7 +831,7 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names)
for (i = 0; i < n; i++) {
if (names[i] > 0) {
struct gl_transform_feedback_object *obj
- = lookup_transform_feedback_object(ctx, names[i]);
+ = _mesa_lookup_transform_feedback_object(ctx, names[i]);
if (obj) {
if (obj->Active) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -912,40 +899,4 @@ _mesa_ResumeTransformFeedback(void)
ctx->Driver.ResumeTransformFeedback(ctx, obj);
}
-
-/**
- * Draw the vertex data in a transform feedback object.
- * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
- * \param name the transform feedback object
- * The number of vertices comes from the transform feedback object.
- * User still has to setup of the vertex attribute info with
- * glVertexPointer, glColorPointer, etc.
- * Part of GL_ARB_transform_feedback2.
- */
-void GLAPIENTRY
-_mesa_DrawTransformFeedback(GLenum mode, GLuint name)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_transform_feedback_object *obj =
- lookup_transform_feedback_object(ctx, name);
-
- if (mode > GL_POLYGON) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glDrawTransformFeedback(mode=0x%x)", mode);
- return;
- }
- if (!obj) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glDrawTransformFeedback(name = %u)", name);
- return;
- }
-
- /* XXX check if EndTransformFeedback has never been called while
- * the object was bound
- */
-
- assert(ctx->Driver.DrawTransformFeedback);
- ctx->Driver.DrawTransformFeedback(ctx, mode, obj);
-}
-
#endif /* FEATURE_EXT_transform_feedback */
diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h
index 9447effa9..8a6672d58 100644
--- a/mesalib/src/mesa/main/transformfeedback.h
+++ b/mesalib/src/mesa/main/transformfeedback.h
@@ -87,6 +87,9 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
/*** GL_ARB_transform_feedback2 ***/
+struct gl_transform_feedback_object *
+_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name);
+
extern void GLAPIENTRY
_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names);
@@ -105,9 +108,6 @@ _mesa_PauseTransformFeedback(void);
extern void GLAPIENTRY
_mesa_ResumeTransformFeedback(void);
-extern void GLAPIENTRY
-_mesa_DrawTransformFeedback(GLenum mode, GLuint name);
-
#else /* FEATURE_EXT_transform_feedback */
static inline GLboolean
diff --git a/mesalib/src/mesa/main/varray.h b/mesalib/src/mesa/main/varray.h
index 6fcc0a336..b6041bd78 100644
--- a/mesalib/src/mesa/main/varray.h
+++ b/mesalib/src/mesa/main/varray.h
@@ -245,6 +245,13 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
const GLvoid *indices,
GLint basevertex);
+#if FEATURE_EXT_transform_feedback
+
+extern void GLAPIENTRY
+_mesa_DrawTransformFeedback(GLenum mode, GLuint name);
+
+#endif
+
extern void GLAPIENTRY
_mesa_PrimitiveRestartIndex(GLuint index);
diff --git a/mesalib/src/mesa/main/vtxfmt.c b/mesalib/src/mesa/main/vtxfmt.c
index 03735d779..f3cca937d 100644
--- a/mesalib/src/mesa/main/vtxfmt.c
+++ b/mesalib/src/mesa/main/vtxfmt.c
@@ -107,6 +107,7 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )
SET_DrawArraysInstancedARB(tab, vfmt->DrawArraysInstanced);
SET_DrawElementsInstancedARB(tab, vfmt->DrawElementsInstanced);
SET_DrawElementsInstancedBaseVertex(tab, vfmt->DrawElementsInstancedBaseVertex);
+ SET_DrawTransformFeedback(tab, vfmt->DrawTransformFeedback);
/* GL_NV_vertex_program */
SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV);
diff --git a/mesalib/src/mesa/program/prog_parameter_layout.c b/mesalib/src/mesa/program/prog_parameter_layout.c
index 28fca3b92..e4f2db3b3 100644
--- a/mesalib/src/mesa/program/prog_parameter_layout.c
+++ b/mesalib/src/mesa/program/prog_parameter_layout.c
@@ -138,6 +138,7 @@ _mesa_layout_parameters(struct asm_parser_state *state)
inst->SrcReg[i].Symbol->param_binding_length);
if (new_begin < 0) {
+ _mesa_free_parameter_list(layout);
return GL_FALSE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c
index afca60976..fb1e4092c 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -266,6 +266,7 @@ get_pixel_transfer_program(struct gl_context *ctx, const struct state_key *key)
if (!fp->Base.Instructions) {
_mesa_error(ctx, GL_OUT_OF_MEMORY,
"generating pixel transfer program");
+ _mesa_free_parameter_list(params);
return NULL;
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
index 250cbb226..4aa0b4e2a 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -256,9 +256,11 @@ static void update_raster_state( struct st_context *st )
/* _NEW_FRAG_CLAMP */
raster->clamp_fragment_color = ctx->Color._ClampFragmentColor;
-
raster->gl_rasterization_rules = 1;
+ /* _NEW_TRANSFORM */
+ raster->rasterizer_discard = ctx->TransformFeedback.RasterDiscard;
+
cso_set_rasterizer(st->cso_context, raster);
}
@@ -273,7 +275,8 @@ const struct st_tracked_state st_update_rasterizer = {
_NEW_POLYGON |
_NEW_PROGRAM |
_NEW_SCISSOR |
- _NEW_FRAG_CLAMP), /* mesa state dependencies*/
+ _NEW_FRAG_CLAMP |
+ _NEW_TRANSFORM), /* mesa state dependencies*/
ST_NEW_VERTEX_PROGRAM, /* state tracker dependencies */
},
update_raster_state /* update function */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
index fa37be0b6..af33bcf86 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
@@ -483,6 +483,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_save_fragment_sampler_views(cso);
cso_save_viewport(cso);
cso_save_fragment_shader(cso);
+ cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
@@ -542,6 +543,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
}
cso_set_vertex_elements(cso, 3, st->velems_util_draw);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
/* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
z = z * 2.0f - 1.0f;
@@ -568,6 +570,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
cso_restore_vertex_buffers(cso);
+ cso_restore_stream_outputs(cso);
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index 61d98aeb9..23700eeb7 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -250,6 +250,7 @@ clear_with_quad(struct gl_context *ctx,
cso_save_viewport(st->cso_context);
cso_save_clip(st->cso_context);
cso_save_fragment_shader(st->cso_context);
+ cso_save_stream_outputs(st->cso_context);
cso_save_vertex_shader(st->cso_context);
cso_save_geometry_shader(st->cso_context);
cso_save_vertex_elements(st->cso_context);
@@ -306,6 +307,7 @@ clear_with_quad(struct gl_context *ctx,
}
cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
cso_set_rasterizer(st->cso_context, &st->clear.raster);
@@ -350,6 +352,7 @@ clear_with_quad(struct gl_context *ctx,
cso_restore_geometry_shader(st->cso_context);
cso_restore_vertex_elements(st->cso_context);
cso_restore_vertex_buffers(st->cso_context);
+ cso_restore_stream_outputs(st->cso_context);
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
index 65b444552..318ba7d06 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -671,6 +671,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_save_samplers(cso);
cso_save_fragment_sampler_views(cso);
cso_save_fragment_shader(cso);
+ cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
@@ -761,6 +762,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
}
cso_set_vertex_elements(cso, 3, st->velems_util_draw);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
/* texture state: */
cso_set_fragment_sampler_views(cso, num_sampler_view, sv);
@@ -796,6 +798,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
cso_restore_vertex_buffers(cso);
+ cso_restore_stream_outputs(cso);
if (write_stencil) {
cso_restore_depth_stencil_alpha(cso);
cso_restore_blend(cso);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
index 332b0d1b6..6144eb99c 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
@@ -227,6 +227,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
cso_save_viewport(cso);
+ cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
@@ -246,6 +247,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
cso_set_vertex_elements(cso, numAttribs, velements);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
/* viewport state: viewport matching window dims */
{
@@ -281,6 +283,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
cso_restore_vertex_buffers(cso);
+ cso_restore_stream_outputs(cso);
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c
index 2e9eb7265..2c21dc9a7 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -1,272 +1,273 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-/**
- * glRasterPos implementation. Basically render a GL_POINT with our
- * private draw module. Plug in a special "rasterpos" stage at the end
- * of the 'draw' pipeline to capture the results and update the current
- * raster pos attributes.
- *
- * Authors:
- * Brian Paul
- */
-
-
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mfeatures.h"
-#include "main/feedback.h"
-
-#include "st_context.h"
-#include "st_atom.h"
-#include "st_draw.h"
-#include "st_cb_rasterpos.h"
-#include "draw/draw_context.h"
-#include "draw/draw_pipe.h"
-#include "vbo/vbo.h"
-
-
-#if FEATURE_rastpos
-
-/**
- * Our special drawing pipeline stage (replaces rasterization).
- */
-struct rastpos_stage
-{
- struct draw_stage stage; /**< Base class */
- struct gl_context *ctx; /**< Rendering context */
-
- /* vertex attrib info we can setup once and re-use */
- struct gl_client_array array[VERT_ATTRIB_MAX];
- const struct gl_client_array *arrays[VERT_ATTRIB_MAX];
- struct _mesa_prim prim;
-};
-
-
-static INLINE struct rastpos_stage *
-rastpos_stage( struct draw_stage *stage )
-{
- return (struct rastpos_stage *) stage;
-}
-
-static void
-rastpos_flush( struct draw_stage *stage, unsigned flags )
-{
- /* no-op */
-}
-
-static void
-rastpos_reset_stipple_counter( struct draw_stage *stage )
-{
- /* no-op */
-}
-
-static void
-rastpos_tri( struct draw_stage *stage, struct prim_header *prim )
-{
- /* should never get here */
- assert(0);
-}
-
-static void
-rastpos_line( struct draw_stage *stage, struct prim_header *prim )
-{
- /* should never get here */
- assert(0);
-}
-
-static void
-rastpos_destroy(struct draw_stage *stage)
-{
- free(stage);
-}
-
-
-/**
- * Update a raster pos attribute from the vertex result if it's present,
- * else copy the current attrib.
- */
-static void
-update_attrib(struct gl_context *ctx, const GLuint *outputMapping,
- const struct vertex_header *vert,
- GLfloat *dest,
- GLuint result, GLuint defaultAttrib)
-{
- const GLfloat *src;
- const GLuint k = outputMapping[result];
- if (k != ~0U)
- src = vert->data[k];
- else
- src = ctx->Current.Attrib[defaultAttrib];
- COPY_4V(dest, src);
-}
-
-
-/**
- * Normally, this function would render a GL_POINT.
- */
-static void
-rastpos_point(struct draw_stage *stage, struct prim_header *prim)
-{
- struct rastpos_stage *rs = rastpos_stage(stage);
- struct gl_context *ctx = rs->ctx;
- struct st_context *st = st_context(ctx);
- const GLfloat height = (GLfloat) ctx->DrawBuffer->Height;
- const GLuint *outputMapping = st->vertex_result_to_slot;
- const GLfloat *pos;
- GLuint i;
-
- /* if we get here, we didn't get clipped */
- ctx->Current.RasterPosValid = GL_TRUE;
-
- /* update raster pos */
- pos = prim->v[0]->data[0];
- ctx->Current.RasterPos[0] = pos[0];
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
- ctx->Current.RasterPos[1] = height - pos[1]; /* invert Y */
- else
- ctx->Current.RasterPos[1] = pos[1];
- ctx->Current.RasterPos[2] = pos[2];
- ctx->Current.RasterPos[3] = pos[3];
-
- /* update other raster attribs */
- update_attrib(ctx, outputMapping, prim->v[0],
- ctx->Current.RasterColor,
- VERT_RESULT_COL0, VERT_ATTRIB_COLOR0);
-
- update_attrib(ctx, outputMapping, prim->v[0],
- ctx->Current.RasterSecondaryColor,
- VERT_RESULT_COL1, VERT_ATTRIB_COLOR1);
-
- for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
- update_attrib(ctx, outputMapping, prim->v[0],
- ctx->Current.RasterTexCoords[i],
- VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);
- }
-
- if (ctx->RenderMode == GL_SELECT) {
- _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
- }
-}
-
-
-/**
- * Create rasterpos "drawing" stage.
- */
-static struct rastpos_stage *
-new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw)
-{
- struct rastpos_stage *rs = ST_CALLOC_STRUCT(rastpos_stage);
- GLuint i;
-
- rs->stage.draw = draw;
- rs->stage.next = NULL;
- rs->stage.point = rastpos_point;
- rs->stage.line = rastpos_line;
- rs->stage.tri = rastpos_tri;
- rs->stage.flush = rastpos_flush;
- rs->stage.destroy = rastpos_destroy;
- rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
- rs->stage.destroy = rastpos_destroy;
- rs->ctx = ctx;
-
- for (i = 0; i < Elements(rs->array); i++) {
- rs->array[i].Size = 4;
- rs->array[i].Type = GL_FLOAT;
- rs->array[i].Format = GL_RGBA;
- rs->array[i].Stride = 0;
- rs->array[i].StrideB = 0;
- rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
- rs->array[i].Enabled = GL_TRUE;
- rs->array[i].Normalized = GL_TRUE;
- rs->array[i].BufferObj = NULL;
- rs->arrays[i] = &rs->array[i];
- }
-
- rs->prim.mode = GL_POINTS;
- rs->prim.indexed = 0;
- rs->prim.begin = 1;
- rs->prim.end = 1;
- rs->prim.weak = 0;
- rs->prim.start = 0;
- rs->prim.count = 1;
-
- return rs;
-}
-
-
-static void
-st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
-{
- struct st_context *st = st_context(ctx);
- struct draw_context *draw = st->draw;
- struct rastpos_stage *rs;
-
- if (st->rastpos_stage) {
- /* get rastpos stage info */
- rs = rastpos_stage(st->rastpos_stage);
- }
- else {
- /* create rastpos draw stage */
- rs = new_draw_rastpos_stage(ctx, draw);
- st->rastpos_stage = &rs->stage;
- }
-
- /* plug our rastpos stage into the draw module */
- draw_set_rasterize_stage(st->draw, st->rastpos_stage);
-
- /* make sure everything's up to date */
- st_validate_state(st);
-
- /* This will get set only if rastpos_point(), above, gets called */
- ctx->Current.RasterPosValid = GL_FALSE;
-
- /* All vertex attribs but position were previously initialized above.
- * Just plug in position pointer now.
- */
- rs->array[0].Ptr = (GLubyte *) v;
-
- /* draw the point */
- st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1);
-
- /* restore draw's rasterization stage depending on rendermode */
- if (ctx->RenderMode == GL_FEEDBACK) {
- draw_set_rasterize_stage(draw, st->feedback_stage);
- }
- else if (ctx->RenderMode == GL_SELECT) {
- draw_set_rasterize_stage(draw, st->selection_stage);
- }
-}
-
-
-
-void st_init_rasterpos_functions(struct dd_function_table *functions)
-{
- functions->RasterPos = st_RasterPos;
-}
-
-#endif /* FEATURE_rastpos */
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+/**
+ * glRasterPos implementation. Basically render a GL_POINT with our
+ * private draw module. Plug in a special "rasterpos" stage at the end
+ * of the 'draw' pipeline to capture the results and update the current
+ * raster pos attributes.
+ *
+ * Authors:
+ * Brian Paul
+ */
+
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mfeatures.h"
+#include "main/feedback.h"
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "st_draw.h"
+#include "st_cb_rasterpos.h"
+#include "draw/draw_context.h"
+#include "draw/draw_pipe.h"
+#include "vbo/vbo.h"
+
+
+#if FEATURE_rastpos
+
+/**
+ * Our special drawing pipeline stage (replaces rasterization).
+ */
+struct rastpos_stage
+{
+ struct draw_stage stage; /**< Base class */
+ struct gl_context *ctx; /**< Rendering context */
+
+ /* vertex attrib info we can setup once and re-use */
+ struct gl_client_array array[VERT_ATTRIB_MAX];
+ const struct gl_client_array *arrays[VERT_ATTRIB_MAX];
+ struct _mesa_prim prim;
+};
+
+
+static INLINE struct rastpos_stage *
+rastpos_stage( struct draw_stage *stage )
+{
+ return (struct rastpos_stage *) stage;
+}
+
+static void
+rastpos_flush( struct draw_stage *stage, unsigned flags )
+{
+ /* no-op */
+}
+
+static void
+rastpos_reset_stipple_counter( struct draw_stage *stage )
+{
+ /* no-op */
+}
+
+static void
+rastpos_tri( struct draw_stage *stage, struct prim_header *prim )
+{
+ /* should never get here */
+ assert(0);
+}
+
+static void
+rastpos_line( struct draw_stage *stage, struct prim_header *prim )
+{
+ /* should never get here */
+ assert(0);
+}
+
+static void
+rastpos_destroy(struct draw_stage *stage)
+{
+ free(stage);
+}
+
+
+/**
+ * Update a raster pos attribute from the vertex result if it's present,
+ * else copy the current attrib.
+ */
+static void
+update_attrib(struct gl_context *ctx, const GLuint *outputMapping,
+ const struct vertex_header *vert,
+ GLfloat *dest,
+ GLuint result, GLuint defaultAttrib)
+{
+ const GLfloat *src;
+ const GLuint k = outputMapping[result];
+ if (k != ~0U)
+ src = vert->data[k];
+ else
+ src = ctx->Current.Attrib[defaultAttrib];
+ COPY_4V(dest, src);
+}
+
+
+/**
+ * Normally, this function would render a GL_POINT.
+ */
+static void
+rastpos_point(struct draw_stage *stage, struct prim_header *prim)
+{
+ struct rastpos_stage *rs = rastpos_stage(stage);
+ struct gl_context *ctx = rs->ctx;
+ struct st_context *st = st_context(ctx);
+ const GLfloat height = (GLfloat) ctx->DrawBuffer->Height;
+ const GLuint *outputMapping = st->vertex_result_to_slot;
+ const GLfloat *pos;
+ GLuint i;
+
+ /* if we get here, we didn't get clipped */
+ ctx->Current.RasterPosValid = GL_TRUE;
+
+ /* update raster pos */
+ pos = prim->v[0]->data[0];
+ ctx->Current.RasterPos[0] = pos[0];
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
+ ctx->Current.RasterPos[1] = height - pos[1]; /* invert Y */
+ else
+ ctx->Current.RasterPos[1] = pos[1];
+ ctx->Current.RasterPos[2] = pos[2];
+ ctx->Current.RasterPos[3] = pos[3];
+
+ /* update other raster attribs */
+ update_attrib(ctx, outputMapping, prim->v[0],
+ ctx->Current.RasterColor,
+ VERT_RESULT_COL0, VERT_ATTRIB_COLOR0);
+
+ update_attrib(ctx, outputMapping, prim->v[0],
+ ctx->Current.RasterSecondaryColor,
+ VERT_RESULT_COL1, VERT_ATTRIB_COLOR1);
+
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+ update_attrib(ctx, outputMapping, prim->v[0],
+ ctx->Current.RasterTexCoords[i],
+ VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);
+ }
+
+ if (ctx->RenderMode == GL_SELECT) {
+ _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
+ }
+}
+
+
+/**
+ * Create rasterpos "drawing" stage.
+ */
+static struct rastpos_stage *
+new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw)
+{
+ struct rastpos_stage *rs = ST_CALLOC_STRUCT(rastpos_stage);
+ GLuint i;
+
+ rs->stage.draw = draw;
+ rs->stage.next = NULL;
+ rs->stage.point = rastpos_point;
+ rs->stage.line = rastpos_line;
+ rs->stage.tri = rastpos_tri;
+ rs->stage.flush = rastpos_flush;
+ rs->stage.destroy = rastpos_destroy;
+ rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
+ rs->stage.destroy = rastpos_destroy;
+ rs->ctx = ctx;
+
+ for (i = 0; i < Elements(rs->array); i++) {
+ rs->array[i].Size = 4;
+ rs->array[i].Type = GL_FLOAT;
+ rs->array[i].Format = GL_RGBA;
+ rs->array[i].Stride = 0;
+ rs->array[i].StrideB = 0;
+ rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
+ rs->array[i].Enabled = GL_TRUE;
+ rs->array[i].Normalized = GL_TRUE;
+ rs->array[i].BufferObj = NULL;
+ rs->arrays[i] = &rs->array[i];
+ }
+
+ rs->prim.mode = GL_POINTS;
+ rs->prim.indexed = 0;
+ rs->prim.begin = 1;
+ rs->prim.end = 1;
+ rs->prim.weak = 0;
+ rs->prim.start = 0;
+ rs->prim.count = 1;
+
+ return rs;
+}
+
+
+static void
+st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
+{
+ struct st_context *st = st_context(ctx);
+ struct draw_context *draw = st->draw;
+ struct rastpos_stage *rs;
+
+ if (st->rastpos_stage) {
+ /* get rastpos stage info */
+ rs = rastpos_stage(st->rastpos_stage);
+ }
+ else {
+ /* create rastpos draw stage */
+ rs = new_draw_rastpos_stage(ctx, draw);
+ st->rastpos_stage = &rs->stage;
+ }
+
+ /* plug our rastpos stage into the draw module */
+ draw_set_rasterize_stage(st->draw, st->rastpos_stage);
+
+ /* make sure everything's up to date */
+ st_validate_state(st);
+
+ /* This will get set only if rastpos_point(), above, gets called */
+ ctx->Current.RasterPosValid = GL_FALSE;
+
+ /* All vertex attribs but position were previously initialized above.
+ * Just plug in position pointer now.
+ */
+ rs->array[0].Ptr = (GLubyte *) v;
+
+ /* draw the point */
+ st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1,
+ NULL);
+
+ /* restore draw's rasterization stage depending on rendermode */
+ if (ctx->RenderMode == GL_FEEDBACK) {
+ draw_set_rasterize_stage(draw, st->feedback_stage);
+ }
+ else if (ctx->RenderMode == GL_SELECT) {
+ draw_set_rasterize_stage(draw, st->selection_stage);
+ }
+}
+
+
+
+void st_init_rasterpos_functions(struct dd_function_table *functions)
+{
+ functions->RasterPos = st_RasterPos;
+}
+
+#endif /* FEATURE_rastpos */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
index 378b4822b..2fc28dc24 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
@@ -1,134 +1,197 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-
-/**
- * Transform feedback functions.
- *
- * \author Brian Paul
- */
-
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "main/mfeatures.h"
-#include "main/transformfeedback.h"
-
-#include "st_cb_xformfb.h"
-
-
-#if FEATURE_EXT_transform_feedback
-
-#if 0
-static struct gl_transform_feedback_object *
-st_new_transform_feedback(struct gl_context *ctx, GLuint name)
-{
- struct gl_transform_feedback_object *obj;
- obj = CALLOC_STRUCT(gl_transform_feedback_object);
- if (obj) {
- obj->Name = name;
- obj->RefCount = 1;
- }
- return obj;
-}
-#endif
-
-#if 0
-static void
-st_delete_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- GLuint i;
-
- for (i = 0; i < Elements(obj->Buffers); i++) {
- _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL);
- }
-
- free(obj);
-}
-#endif
-
-
-static void
-st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_end_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_pause_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_resume_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj)
-{
- /* XXX to do */
- /*
- * Get number of vertices in obj's feedback buffer.
- * Call ctx->Exec.DrawArrays(mode, 0, count);
- */
-}
-
-
-void
-st_init_xformfb_functions(struct dd_function_table *functions)
-{
- /* let core Mesa plug in its functions */
- _mesa_init_transform_feedback_functions(functions);
-
- /* then override a few: */
- functions->BeginTransformFeedback = st_begin_transform_feedback;
- functions->EndTransformFeedback = st_end_transform_feedback;
- functions->PauseTransformFeedback = st_pause_transform_feedback;
- functions->ResumeTransformFeedback = st_resume_transform_feedback;
- functions->DrawTransformFeedback = st_draw_transform_feedback;
-}
-
-#endif /* FEATURE_EXT_transform_feedback */
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+
+/**
+ * Transform feedback functions.
+ *
+ * \author Brian Paul
+ * Marek Olšák
+ */
+
+
+#include "main/bufferobj.h"
+#include "main/context.h"
+#include "main/mfeatures.h"
+#include "main/transformfeedback.h"
+
+#include "st_cb_bufferobjects.h"
+#include "st_cb_xformfb.h"
+#include "st_context.h"
+
+#include "pipe/p_context.h"
+#include "util/u_draw.h"
+#include "util/u_inlines.h"
+#include "cso_cache/cso_context.h"
+
+#if FEATURE_EXT_transform_feedback
+
+struct st_transform_feedback_object {
+ struct gl_transform_feedback_object base;
+
+ unsigned num_targets;
+ struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
+};
+
+
+static struct gl_transform_feedback_object *
+st_new_transform_feedback(struct gl_context *ctx, GLuint name)
+{
+ struct st_transform_feedback_object *obj;
+
+ obj = CALLOC_STRUCT(st_transform_feedback_object);
+ if (!obj)
+ return NULL;
+
+ obj->base.Name = name;
+ obj->base.RefCount = 1;
+ return &obj->base;
+}
+
+
+static void
+st_delete_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+ unsigned i;
+
+ /* Unreference targets. */
+ for (i = 0; i < sobj->num_targets; i++) {
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ }
+
+ for (i = 0; i < Elements(sobj->base.Buffers); i++) {
+ _mesa_reference_buffer_object(ctx, &sobj->base.Buffers[i], NULL);
+ }
+
+ free(obj);
+}
+
+
+/* XXX Do we really need the mode? */
+static void
+st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+ unsigned i, max_num_targets;
+
+ max_num_targets = MIN2(Elements(sobj->base.Buffers),
+ Elements(sobj->targets));
+
+ /* Convert the transform feedback state into the gallium representation. */
+ for (i = 0; i < max_num_targets; i++) {
+ struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]);
+
+ if (bo) {
+ /* Check whether we need to recreate the target. */
+ if (!sobj->targets[i] ||
+ sobj->targets[i]->buffer != bo->buffer ||
+ sobj->targets[i]->buffer_offset != sobj->base.Offset[i] ||
+ sobj->targets[i]->buffer_size != sobj->base.Size[i]) {
+ /* Create a new target. */
+ struct pipe_stream_output_target *so_target =
+ pipe->create_stream_output_target(pipe, bo->buffer,
+ sobj->base.Offset[i],
+ sobj->base.Size[i]);
+
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ sobj->targets[i] = so_target;
+ }
+
+ sobj->num_targets = i+1;
+ } else {
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ }
+ }
+
+ /* Start writing at the beginning of each target. */
+ cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
+ 0);
+}
+
+
+static void
+st_stop_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_context *st = st_context(ctx);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
+}
+
+
+static void
+st_resume_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+
+ cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
+ ~0);
+}
+
+/* Set count_from_stream_output to any stream output target
+ * from the transform feedback object. */
+void
+st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
+ struct pipe_draw_info *out)
+{
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+ unsigned i;
+
+ for (i = 0; i < Elements(sobj->targets); i++) {
+ if (sobj->targets[i]) {
+ out->count_from_stream_output = sobj->targets[i];
+ return;
+ }
+ }
+
+ assert(0);
+ out->count_from_stream_output = NULL;
+}
+
+
+void
+st_init_xformfb_functions(struct dd_function_table *functions)
+{
+ functions->NewTransformFeedback = st_new_transform_feedback;
+ functions->DeleteTransformFeedback = st_delete_transform_feedback;
+ functions->BeginTransformFeedback = st_begin_transform_feedback;
+ functions->EndTransformFeedback = st_stop_transform_feedback;
+ functions->PauseTransformFeedback = st_stop_transform_feedback;
+ functions->ResumeTransformFeedback = st_resume_transform_feedback;
+}
+
+#endif /* FEATURE_EXT_transform_feedback */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.h b/mesalib/src/mesa/state_tracker/st_cb_xformfb.h
index e07f500ce..c5261b39b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.h
+++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.h
@@ -1,51 +1,63 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#ifndef ST_CB_XFORMFB_H
-#define ST_CB_XFORMFB_H
-
-
-#include "main/compiler.h"
-#include "main/mfeatures.h"
-
-struct dd_function_table;
-
-#if FEATURE_EXT_transform_feedback
-
-extern void
-st_init_xformfb_functions(struct dd_function_table *functions);
-
-#else
-
-static INLINE void
-st_init_xformfb_functions(struct dd_function_table *functions)
-{
-}
-
-#endif /* FEATURE_EXT_transform_feedback */
-
-#endif /* ST_CB_XFORMFB_H */
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+#ifndef ST_CB_XFORMFB_H
+#define ST_CB_XFORMFB_H
+
+
+#include "main/compiler.h"
+#include "main/mfeatures.h"
+
+struct dd_function_table;
+struct gl_transform_feedback_object;
+struct pipe_draw_info;
+
+#if FEATURE_EXT_transform_feedback
+
+extern void
+st_init_xformfb_functions(struct dd_function_table *functions);
+
+extern void
+st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
+ struct pipe_draw_info *out);
+
+#else
+
+static INLINE void
+st_init_xformfb_functions(struct dd_function_table *functions)
+{
+}
+
+static INLINE void
+st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
+ struct pipe_draw_info *out)
+{
+}
+
+#endif /* FEATURE_EXT_transform_feedback */
+
+#endif /* ST_CB_XFORMFB_H */
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index fd1c8ee48..87a997865 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -51,6 +51,7 @@
#include "st_context.h"
#include "st_atom.h"
#include "st_cb_bufferobjects.h"
+#include "st_cb_xformfb.h"
#include "st_draw.h"
#include "st_program.h"
@@ -926,7 +927,8 @@ st_draw_vbo(struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index)
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
@@ -1032,6 +1034,11 @@ st_draw_vbo(struct gl_context *ctx,
info.restart_index = ctx->Array.RestartIndex;
}
+ /* Set info.count_from_stream_output. */
+ if (tfb_vertcount) {
+ st_transform_feedback_draw_init(tfb_vertcount, &info);
+ }
+
/* do actual drawing */
for (i = 0; i < nr_prims; i++) {
info.mode = translate_prim( ctx, prims[i].mode );
@@ -1044,7 +1051,10 @@ st_draw_vbo(struct gl_context *ctx,
info.max_index = info.start + info.count - 1;
}
- if (info.primitive_restart) {
+ if (info.count_from_stream_output) {
+ pipe->draw_vbo(pipe, &info);
+ }
+ else if (info.primitive_restart) {
if (st->sw_primitive_restart) {
/* Handle primitive restart for drivers that doesn't support it */
handle_fallback_primitive_restart(pipe, ib, &ibuffer, &info);
diff --git a/mesalib/src/mesa/state_tracker/st_draw.h b/mesalib/src/mesa/state_tracker/st_draw.h
index 23e1c7821..2623cdbb1 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.h
+++ b/mesalib/src/mesa/state_tracker/st_draw.h
@@ -1,91 +1,93 @@
-/**************************************************************************
- *
- * Copyright 2004 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#ifndef ST_DRAW_H
-#define ST_DRAW_H
-
-#include "main/compiler.h"
-#include "main/glheader.h"
-
-struct _mesa_index_buffer;
-struct _mesa_prim;
-struct gl_client_array;
-struct gl_context;
-struct st_context;
-
-void st_init_draw( struct st_context *st );
-
-void st_destroy_draw( struct st_context *st );
-
-extern void
-st_draw_vbo(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- const struct _mesa_prim *prims,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLboolean index_bounds_valid,
- GLuint min_index,
- GLuint max_index);
-
-extern void
-st_feedback_draw_vbo(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- const struct _mesa_prim *prims,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLboolean index_bounds_valid,
- GLuint min_index,
- GLuint max_index);
-
-/* Internal function:
- */
-extern enum pipe_format
-st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
- GLboolean normalized);
-
-
-/**
- * When drawing with VBOs, the addresses specified with
- * glVertex/Color/TexCoordPointer() are really offsets into the VBO, not real
- * addresses. At some point we need to convert those pointers to offsets.
- * This function is basically a cast wrapper to avoid warnings when building
- * in 64-bit mode.
- */
-static INLINE unsigned
-pointer_to_offset(const void *ptr)
-{
- return (unsigned) (((unsigned long) ptr) & 0xffffffffUL);
-}
-
-
-#endif
+/**************************************************************************
+ *
+ * Copyright 2004 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#ifndef ST_DRAW_H
+#define ST_DRAW_H
+
+#include "main/compiler.h"
+#include "main/glheader.h"
+
+struct _mesa_index_buffer;
+struct _mesa_prim;
+struct gl_client_array;
+struct gl_context;
+struct st_context;
+
+void st_init_draw( struct st_context *st );
+
+void st_destroy_draw( struct st_context *st );
+
+extern void
+st_draw_vbo(struct gl_context *ctx,
+ const struct gl_client_array **arrays,
+ const struct _mesa_prim *prims,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount);
+
+extern void
+st_feedback_draw_vbo(struct gl_context *ctx,
+ const struct gl_client_array **arrays,
+ const struct _mesa_prim *prims,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount);
+
+/* Internal function:
+ */
+extern enum pipe_format
+st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
+ GLboolean normalized);
+
+
+/**
+ * When drawing with VBOs, the addresses specified with
+ * glVertex/Color/TexCoordPointer() are really offsets into the VBO, not real
+ * addresses. At some point we need to convert those pointers to offsets.
+ * This function is basically a cast wrapper to avoid warnings when building
+ * in 64-bit mode.
+ */
+static INLINE unsigned
+pointer_to_offset(const void *ptr)
+{
+ return (unsigned) (((unsigned long) ptr) & 0xffffffffUL);
+}
+
+
+#endif
diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
index a7e6a0f1b..4c1e67495 100644
--- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c
+++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
@@ -97,7 +97,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index)
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 457d5d62a..47a178b8b 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -221,6 +221,13 @@ void st_init_limits(struct st_context *st)
c->UniformBooleanTrue = ~0;
+ c->MaxTransformFeedbackSeparateAttribs =
+ screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS);
+ c->MaxTransformFeedbackSeparateComponents =
+ screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS);
+ c->MaxTransformFeedbackInterleavedComponents =
+ screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS);
+
c->StripTextureBorder = GL_TRUE;
c->GLSLSkipStrictMaxUniformLimitCheck =
@@ -682,4 +689,12 @@ void st_init_extensions(struct st_context *st)
PIPE_BIND_SAMPLER_VIEW))
ctx->Extensions.ARB_texture_rgb10_a2ui = GL_TRUE;
+ if (screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) {
+ ctx->Extensions.EXT_transform_feedback = GL_TRUE;
+
+ if (screen->get_param(screen,
+ PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME) != 0) {
+ ctx->Extensions.ARB_transform_feedback2 = GL_TRUE;
+ }
+ }
}
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 9ef65c8fd..b929806ad 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -5095,4 +5095,31 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
return GL_TRUE;
}
+void
+st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi,
+ const GLuint outputMapping[],
+ struct pipe_stream_output_info *so)
+{
+ static unsigned comps_to_mask[] = {
+ 0,
+ TGSI_WRITEMASK_X,
+ TGSI_WRITEMASK_XY,
+ TGSI_WRITEMASK_XYZ,
+ TGSI_WRITEMASK_XYZW
+ };
+ unsigned i;
+ struct gl_transform_feedback_info *info =
+ &glsl_to_tgsi->shader_program->LinkedTransformFeedback;
+
+ for (i = 0; i < info->NumOutputs; i++) {
+ assert(info->Outputs[i].NumComponents < Elements(comps_to_mask));
+ so->output[i].register_index =
+ outputMapping[info->Outputs[i].OutputRegister];
+ so->output[i].register_mask =
+ comps_to_mask[info->Outputs[i].NumComponents];
+ so->output[i].output_buffer = info->Outputs[i].OutputBuffer;
+ }
+ so->num_outputs = info->NumOutputs;
+}
+
} /* extern "C" */
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
index fafe52e31..1f71f33fd 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
@@ -66,6 +66,12 @@ st_new_shader_program(struct gl_context *ctx, GLuint name);
GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
+void
+st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi,
+ const GLuint outputMapping[],
+ struct pipe_stream_output_info *so);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index 04d3ef60f..b83c56165 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -367,6 +367,12 @@ st_translate_vertex_program(struct st_context *st,
ureg_destroy( ureg );
+ if (stvp->glsl_to_tgsi) {
+ st_translate_stream_output_info(stvp->glsl_to_tgsi,
+ stvp->result_to_output,
+ &vpv->tgsi.stream_output);
+ }
+
vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi);
if (ST_DEBUG & DEBUG_TGSI) {
@@ -994,6 +1000,12 @@ st_translate_geometry_program(struct st_context *st,
stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
ureg_destroy( ureg );
+ if (stgp->glsl_to_tgsi) {
+ st_translate_stream_output_info(stgp->glsl_to_tgsi,
+ outputMapping,
+ &stgp->tgsi.stream_output);
+ }
+
/* fill in new variant */
gpv->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
gpv->key = *key;
diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c
index 2817ec12f..803ad2e89 100644
--- a/mesalib/src/mesa/swrast/s_blit.c
+++ b/mesalib/src/mesa/swrast/s_blit.c
@@ -478,7 +478,15 @@ simple_blit(struct gl_context *ctx,
ASSERT(srcX1 - srcX0 == dstX1 - dstX0);
ASSERT(srcY1 - srcY0 == dstY1 - dstY0);
- /* determine if copy should be bottom-to-top or top-to-bottom */
+ /* From the GL_ARB_framebuffer_object spec:
+ *
+ * "If the source and destination buffers are identical, and the source
+ * and destination rectangles overlap, the result of the blit operation
+ * is undefined."
+ *
+ * However, we provide the expected result anyway by flipping the order of
+ * the memcpy of rows.
+ */
if (srcY0 > dstY0) {
/* src above dst: copy bottom-to-top */
yStep = 1;
diff --git a/mesalib/src/mesa/swrast/s_drawpix.c b/mesalib/src/mesa/swrast/s_drawpix.c
index b6c433753..7259881c1 100644
--- a/mesalib/src/mesa/swrast/s_drawpix.c
+++ b/mesalib/src/mesa/swrast/s_drawpix.c
@@ -625,7 +625,8 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
GL_DEPTH_STENCIL_EXT, type, i, 0);
if (ctx->Depth.Mask) {
- if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24) {
+ if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24 &&
+ type == GL_UNSIGNED_INT_24_8) {
/* fast path 24-bit zbuffer */
GLuint zValues[MAX_WIDTH];
GLint j;
@@ -639,7 +640,8 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
else
depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);
}
- else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16) {
+ else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16 &&
+ type == GL_UNSIGNED_INT_24_8) {
/* fast path 16-bit zbuffer */
GLushort zValues[MAX_WIDTH];
GLint j;
diff --git a/mesalib/src/mesa/tnl/t_draw.c b/mesalib/src/mesa/tnl/t_draw.c
index 03424d7a4..83ded1949 100644
--- a/mesalib/src/mesa/tnl/t_draw.c
+++ b/mesalib/src/mesa/tnl/t_draw.c
@@ -430,7 +430,8 @@ void _tnl_vbo_draw_prims(struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index)
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount)
{
if (!index_bounds_valid)
vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
diff --git a/mesalib/src/mesa/tnl/tnl.h b/mesalib/src/mesa/tnl/tnl.h
index 3ca0c5ebb..d3889811e 100644
--- a/mesalib/src/mesa/tnl/tnl.h
+++ b/mesalib/src/mesa/tnl/tnl.h
@@ -1,103 +1,104 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * 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 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
- * BRIAN PAUL 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.
- *
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef _TNL_H
-#define _TNL_H
-
-#include "main/glheader.h"
-
-struct gl_client_array;
-struct gl_context;
-struct gl_program;
-
-
-/* These are the public-access functions exported from tnl. (A few
- * more are currently hooked into dispatch directly by the module
- * itself.)
- */
-extern GLboolean
-_tnl_CreateContext( struct gl_context *ctx );
-
-extern void
-_tnl_DestroyContext( struct gl_context *ctx );
-
-extern void
-_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state );
-
-/* Functions to revive the tnl module after being unhooked from
- * dispatch and/or driver callbacks.
- */
-
-extern void
-_tnl_wakeup( struct gl_context *ctx );
-
-/* Driver configuration options:
- */
-extern void
-_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag );
-
-
-/* Control whether T&L does per-vertex fog
- */
-extern void
-_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value );
-
-extern void
-_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value );
-
-extern GLboolean
-_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program);
-
-struct _mesa_prim;
-struct _mesa_index_buffer;
-
-void
-_tnl_draw_prims( struct gl_context *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_prim *prim,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLuint min_index,
- GLuint max_index);
-
-void
-_tnl_vbo_draw_prims( struct gl_context *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_prim *prim,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLboolean index_bounds_valid,
- GLuint min_index,
- GLuint max_index);
-
-extern void
-_mesa_load_tracked_matrices(struct gl_context *ctx);
-
-extern void
-_tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]);
-
-#endif
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * 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 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
+ * BRIAN PAUL 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.
+ *
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef _TNL_H
+#define _TNL_H
+
+#include "main/glheader.h"
+
+struct gl_client_array;
+struct gl_context;
+struct gl_program;
+
+
+/* These are the public-access functions exported from tnl. (A few
+ * more are currently hooked into dispatch directly by the module
+ * itself.)
+ */
+extern GLboolean
+_tnl_CreateContext( struct gl_context *ctx );
+
+extern void
+_tnl_DestroyContext( struct gl_context *ctx );
+
+extern void
+_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state );
+
+/* Functions to revive the tnl module after being unhooked from
+ * dispatch and/or driver callbacks.
+ */
+
+extern void
+_tnl_wakeup( struct gl_context *ctx );
+
+/* Driver configuration options:
+ */
+extern void
+_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag );
+
+
+/* Control whether T&L does per-vertex fog
+ */
+extern void
+_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value );
+
+extern void
+_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value );
+
+extern GLboolean
+_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program);
+
+struct _mesa_prim;
+struct _mesa_index_buffer;
+
+void
+_tnl_draw_prims( struct gl_context *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index);
+
+void
+_tnl_vbo_draw_prims( struct gl_context *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount );
+
+extern void
+_mesa_load_tracked_matrices(struct gl_context *ctx);
+
+extern void
+_tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]);
+
+#endif
diff --git a/mesalib/src/mesa/vbo/vbo.h b/mesalib/src/mesa/vbo/vbo.h
index 9fbb07f3d..f357657af 100644
--- a/mesalib/src/mesa/vbo/vbo.h
+++ b/mesalib/src/mesa/vbo/vbo.h
@@ -36,6 +36,7 @@
struct gl_client_array;
struct gl_context;
+struct gl_transform_feedback_object;
struct _mesa_prim {
GLuint mode:8; /**< GL_POINTS, GL_LINES, GL_QUAD_STRIP, etc */
@@ -77,7 +78,8 @@ typedef void (*vbo_draw_func)( struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index );
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount );
diff --git a/mesalib/src/mesa/vbo/vbo_context.h b/mesalib/src/mesa/vbo/vbo_context.h
index ef8a2a2b6..1a1cc928b 100644
--- a/mesalib/src/mesa/vbo/vbo_context.h
+++ b/mesalib/src/mesa/vbo/vbo_context.h
@@ -67,6 +67,7 @@ struct vbo_context {
struct gl_client_array *generic_currval;
struct gl_client_array *mat_currval;
+ /** Map VERT_ATTRIB_x to VBO_ATTRIB_y */
GLuint map_vp_none[VERT_ATTRIB_MAX];
GLuint map_vp_arb[VERT_ATTRIB_MAX];
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index 97221a54d..a6e41e9c5 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -34,6 +34,7 @@
#include "main/bufferobj.h"
#include "main/enums.h"
#include "main/macros.h"
+#include "main/transformfeedback.h"
#include "vbo_context.h"
@@ -608,7 +609,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
/* draw one or two prims */
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, primCount, NULL,
- GL_TRUE, start, start + count - 1);
+ GL_TRUE, start, start + count - 1, NULL);
}
}
else {
@@ -618,7 +619,8 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL,
- GL_TRUE, start, start + count - 1);
+ GL_TRUE, start, start + count - 1,
+ NULL);
}
}
@@ -824,7 +826,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib,
- index_bounds_valid, start, end );
+ index_bounds_valid, start, end, NULL );
}
@@ -1168,7 +1170,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib,
- GL_FALSE, ~0, ~0);
+ GL_FALSE, ~0, ~0, NULL);
} else {
/* render one prim at a time */
for (i = 0; i < primcount; i++) {
@@ -1193,7 +1195,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
- GL_FALSE, ~0, ~0);
+ GL_FALSE, ~0, ~0, NULL);
}
}
@@ -1245,6 +1247,76 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
basevertex);
}
+#if FEATURE_EXT_transform_feedback
+
+static void
+vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
+ struct gl_transform_feedback_object *obj,
+ GLuint numInstances)
+{
+ struct vbo_context *vbo = vbo_context(ctx);
+ struct vbo_exec_context *exec = &vbo->exec;
+ struct _mesa_prim prim[2];
+
+ vbo_bind_arrays(ctx);
+
+ /* Again... because we may have changed the bitmask of per-vertex varying
+ * attributes. If we regenerate the fixed-function vertex program now
+ * we may be able to prune down the number of vertex attributes which we
+ * need in the shader.
+ */
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ /* init most fields to zero */
+ memset(prim, 0, sizeof(prim));
+ prim[0].begin = 1;
+ prim[0].end = 1;
+ prim[0].mode = mode;
+ prim[0].num_instances = numInstances;
+
+ /* Maybe we should do some primitive splitting for primitive restart
+ * (like in DrawArrays), but we have no way to know how many vertices
+ * will be rendered. */
+
+ check_buffers_are_unmapped(exec->array.inputs);
+ vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL,
+ GL_TRUE, 0, 0, obj);
+}
+
+/**
+ * Like DrawArrays, but take the count from a transform feedback object.
+ * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
+ * \param name the transform feedback object
+ * User still has to setup of the vertex attribute info with
+ * glVertexPointer, glColorPointer, etc.
+ * Part of GL_ARB_transform_feedback2.
+ */
+static void GLAPIENTRY
+vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_transform_feedback_object *obj =
+ _mesa_lookup_transform_feedback_object(ctx, name);
+
+ if (MESA_VERBOSE & VERBOSE_DRAW)
+ _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
+ _mesa_lookup_enum_by_nr(mode), name);
+
+ if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj)) {
+ return;
+ }
+
+ FLUSH_CURRENT(ctx, 0);
+
+ if (!_mesa_valid_to_render(ctx, "glDrawTransformFeedback")) {
+ return;
+ }
+
+ vbo_draw_transform_feedback(ctx, mode, obj, 1);
+}
+
+#endif
/**
* Plug in the immediate-mode vertex array drawing commands into the
@@ -1263,6 +1335,7 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex;
+ exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback;
}
@@ -1338,3 +1411,13 @@ _mesa_MultiDrawElementsBaseVertex(GLenum mode,
vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
primcount, basevertex);
}
+
+#if FEATURE_EXT_transform_feedback
+
+void GLAPIENTRY
+_mesa_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+ vbo_exec_DrawTransformFeedback(mode, name);
+}
+
+#endif
diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c
index 4962b54e1..dd5363beb 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_draw.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c
@@ -411,7 +411,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped)
NULL,
GL_TRUE,
0,
- exec->vtx.vert_count - 1);
+ exec->vtx.vert_count - 1,
+ NULL);
/* If using a real VBO, get new storage -- unless asked not to.
*/
diff --git a/mesalib/src/mesa/vbo/vbo_rebase.c b/mesalib/src/mesa/vbo/vbo_rebase.c
index 97c8d1297..597a8f469 100644
--- a/mesalib/src/mesa/vbo/vbo_rebase.c
+++ b/mesalib/src/mesa/vbo/vbo_rebase.c
@@ -233,7 +233,8 @@ void vbo_rebase_prims( struct gl_context *ctx,
ib,
GL_TRUE,
0,
- max_index - min_index );
+ max_index - min_index,
+ NULL );
if (tmp_indices)
free(tmp_indices);
diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c
index 9d8bada04..952136747 100644
--- a/mesalib/src/mesa/vbo/vbo_save_api.c
+++ b/mesalib/src/mesa/vbo/vbo_save_api.c
@@ -999,6 +999,16 @@ _save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
static void GLAPIENTRY
+_save_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ (void) mode;
+ (void) name;
+ _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback");
+}
+
+
+static void GLAPIENTRY
_save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -1347,6 +1357,7 @@ _save_vtxfmt_init(struct gl_context *ctx)
vfmt->DrawRangeElements = _save_DrawRangeElements;
vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
+ vfmt->DrawTransformFeedback = _save_DrawTransformFeedback;
vfmt->MultiDrawElementsEXT = _save_MultiDrawElements;
vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex;
}
diff --git a/mesalib/src/mesa/vbo/vbo_save_draw.c b/mesalib/src/mesa/vbo/vbo_save_draw.c
index 0773786b3..fa93ca48f 100644
--- a/mesalib/src/mesa/vbo/vbo_save_draw.c
+++ b/mesalib/src/mesa/vbo/vbo_save_draw.c
@@ -299,7 +299,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
NULL,
GL_TRUE,
0, /* Node is a VBO, so this is ok */
- node->count - 1);
+ node->count - 1,
+ NULL);
}
}
diff --git a/mesalib/src/mesa/vbo/vbo_split_copy.c b/mesalib/src/mesa/vbo/vbo_split_copy.c
index 4dcf71ef5..b53293c31 100644
--- a/mesalib/src/mesa/vbo/vbo_split_copy.c
+++ b/mesalib/src/mesa/vbo/vbo_split_copy.c
@@ -196,7 +196,8 @@ flush( struct copy_context *copy )
&copy->dstib,
GL_TRUE,
0,
- copy->dstbuf_nr - 1 );
+ copy->dstbuf_nr - 1,
+ NULL );
/* Reset all pointers:
*/
diff --git a/mesalib/src/mesa/vbo/vbo_split_inplace.c b/mesalib/src/mesa/vbo/vbo_split_inplace.c
index f6aa576b6..9e596f668 100644
--- a/mesalib/src/mesa/vbo/vbo_split_inplace.c
+++ b/mesalib/src/mesa/vbo/vbo_split_inplace.c
@@ -89,7 +89,8 @@ static void flush_vertex( struct split_context *split )
split->ib ? &ib : NULL,
!split->ib,
split->min_index,
- split->max_index);
+ split->max_index,
+ NULL);
split->dstprim_nr = 0;
split->min_index = ~0;
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index 27bf6abfd..518eb06a9 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -212,7 +212,7 @@ AC_CHECK_FUNC([dlopen], [],
AC_SUBST(DLOPEN_LIBS)
dnl Checks for library functions.
-AC_CHECK_FUNCS([backtrace ffs \
+AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \
getdtablesize getifaddrs getpeereid getpeerucred getzoneid \
mmap shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
AC_REPLACE_FUNCS([strcasecmp strcasestr strlcat strlcpy strndup])
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index 569695c8a..f51be7e9c 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -72,8 +72,8 @@
* These paths define the way the config file search is done. The escape
* sequences are documented in parser/scan.c.
*/
-#ifndef ROOT_CONFIGPATH
-#define ROOT_CONFIGPATH "%A," "%R," \
+#ifndef ALL_CONFIGPATH
+#define ALL_CONFIGPATH "%A," "%R," \
"/etc/X11/%R," "%P/etc/X11/%R," \
"%E," "%F," \
"/etc/X11/%F," "%P/etc/X11/%F," \
@@ -83,8 +83,8 @@
"%P/lib/X11/%X.%H," \
"%P/lib/X11/%X"
#endif
-#ifndef USER_CONFIGPATH
-#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
+#ifndef RESTRICTED_CONFIGPATH
+#define RESTRICTED_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
"/etc/X11/%G," "%P/etc/X11/%G," \
"/etc/X11/%X," "/etc/%X," \
"%P/etc/X11/%X.%H," \
@@ -92,14 +92,14 @@
"%P/lib/X11/%X.%H," \
"%P/lib/X11/%X"
#endif
-#ifndef ROOT_CONFIGDIRPATH
-#define ROOT_CONFIGDIRPATH "%A," "%R," \
+#ifndef ALL_CONFIGDIRPATH
+#define ALL_CONFIGDIRPATH "%A," "%R," \
"/etc/X11/%R," "%C/X11/%R," \
"/etc/X11/%X," "%C/X11/%X"
#endif
-#ifndef USER_CONFIGDIRPATH
-#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
- "/etc/X11/%X," "%C/X11/%X"
+#ifndef RESTRICTED_CONFIGDIRPATH
+#define RESTRICTED_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
+ "/etc/X11/%X," "%C/X11/%X"
#endif
#ifndef SYS_CONFIGDIRPATH
#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
@@ -2310,12 +2310,12 @@ xf86HandleConfigFile(Bool autoconfig)
MessageType filefrom = X_DEFAULT;
MessageType dirfrom = X_DEFAULT;
- if (getuid() == 0) {
- filesearch = ROOT_CONFIGPATH;
- dirsearch = ROOT_CONFIGDIRPATH;
+ if (!xf86PrivsElevated()) {
+ filesearch = ALL_CONFIGPATH;
+ dirsearch = ALL_CONFIGDIRPATH;
} else {
- filesearch = USER_CONFIGPATH;
- dirsearch = USER_CONFIGDIRPATH;
+ filesearch = RESTRICTED_CONFIGPATH;
+ dirsearch = RESTRICTED_CONFIGDIRPATH;
}
if (xf86ConfigFile)
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index c1e48eed2..5263b5f73 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -238,6 +238,65 @@ xf86PrintMarkers(void)
LogPrintMarkers();
}
+Bool xf86PrivsElevated(void)
+{
+ static Bool privsTested = FALSE;
+ static Bool privsElevated = TRUE;
+
+ if (!privsTested) {
+#if defined(WIN32)
+ privsElevated = FALSE;
+#else
+ if ((getuid() != geteuid()) || (getgid() != getegid())) {
+ privsElevated = TRUE;
+ } else {
+#if defined(HAVE_ISSETUGID)
+ privsElevated = issetugid();
+#elif defined(HAVE_GETRESUID)
+ uid_t ruid, euid, suid;
+ gid_t rgid, egid, sgid;
+
+ if ((getresuid(&ruid, &euid, &suid) == 0) &&
+ (getresgid(&rgid, &egid, &sgid) == 0)) {
+ privsElevated = (euid != suid) || (egid != sgid);
+ }
+ else {
+ printf("Failed getresuid or getresgid");
+ /* Something went wrong, make defensive assumption */
+ privsElevated = TRUE;
+ }
+#else
+ if (getuid()==0) {
+ /* running as root: uid==euid==0 */
+ privsElevated = FALSE;
+ }
+ else {
+ /*
+ * If there are saved ID's the process might still be privileged
+ * even though the above test succeeded. If issetugid() and
+ * getresgid() aren't available, test this by trying to set
+ * euid to 0.
+ */
+ unsigned int oldeuid;
+ oldeuid = geteuid();
+
+ if (seteuid(0) != 0) {
+ privsElevated = FALSE;
+ } else {
+ if (seteuid(oldeuid) != 0) {
+ FatalError("Failed to drop privileges. Exiting\n");
+ }
+ privsElevated = TRUE;
+ }
+ }
+#endif
+ }
+#endif
+ privsTested = TRUE;
+ }
+ return privsElevated;
+}
+
static Bool
xf86CreateRootWindow(WindowPtr pWin)
{
@@ -872,7 +931,7 @@ OsVendorInit(void)
#ifdef O_NONBLOCK
if (!beenHere) {
- if (geteuid() == 0 && getuid() != geteuid())
+ if (xf86PrivsElevated())
{
int status;
@@ -1043,10 +1102,11 @@ ddxProcessArgument(int argc, char **argv, int i)
FatalError("Required argument to %s not specified\n", argv[i]); \
}
- /* First the options that are only allowed for root */
+ /* First the options that are not allowed with elevated privileges */
if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
- if ( (geteuid() == 0) && (getuid() != 0) ) {
- FatalError("The '%s' option can only be used by root.\n", argv[i]);
+ if (xf86PrivsElevated()) {
+ FatalError("The '%s' option cannot be used with "
+ "elevated privileges.\n", argv[i]);
}
else if (!strcmp(argv[i], "-modulepath"))
{
@@ -1074,9 +1134,9 @@ ddxProcessArgument(int argc, char **argv, int i)
if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
{
CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
+ "\tWith elevated privileges, the file specified with %s must be\n"
"\ta relative path and must not contain any \"..\" elements.\n"
"\tUsing default "__XCONFIGFILE__" search path.\n\n",
argv[i], argv[i]);
@@ -1087,9 +1147,9 @@ ddxProcessArgument(int argc, char **argv, int i)
if (!strcmp(argv[i], "-configdir"))
{
CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
+ "\tWith elevated privileges, the file specified with %s must be\n"
"\ta relative path and must not contain any \"..\" elements.\n"
"\tUsing default "__XCONFIGDIR__" search path.\n\n",
argv[i], argv[i]);
@@ -1375,7 +1435,7 @@ ddxUseMsg(void)
ErrorF("\n");
ErrorF("\n");
ErrorF("Device Dependent Usage\n");
- if (getuid() == 0 || geteuid() != 0)
+ if (!xf86PrivsElevated())
{
ErrorF("-modulepath paths specify the module search path\n");
ErrorF("-logfile file specify a log file name\n");
diff --git a/xorg-server/hw/xfree86/common/xf86Priv.h b/xorg-server/hw/xfree86/common/xf86Priv.h
index e0b18098e..255407b48 100644
--- a/xorg-server/hw/xfree86/common/xf86Priv.h
+++ b/xorg-server/hw/xfree86/common/xf86Priv.h
@@ -145,6 +145,7 @@ extern _X_EXPORT Bool xf86LoadModules(char **list, pointer *optlist);
extern _X_EXPORT int xf86SetVerbosity(int verb);
extern _X_EXPORT int xf86SetLogVerbosity(int verb);
extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only );
+extern _X_EXPORT Bool xf86PrivsElevated(void);
#endif /* _NO_XF86_PROTOTYPES */
diff --git a/xorg-server/include/xorg-config.h.in b/xorg-server/include/xorg-config.h.in
index 6b9230f3c..2cc416ae7 100644
--- a/xorg-server/include/xorg-config.h.in
+++ b/xorg-server/include/xorg-config.h.in
@@ -130,4 +130,10 @@
/* Use libpciaccess */
#undef XSERVER_LIBPCIACCESS
+/* Have setugid */
+#undef HAVE_ISSETUGID
+
+/* Have getresuid */
+#undef HAVE_GETRESUID
+
#endif /* _XORG_CONFIG_H_ */