aboutsummaryrefslogtreecommitdiff
path: root/mesalib
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib')
-rw-r--r--mesalib/configs/autoconf.in3
-rw-r--r--mesalib/configure.ac95
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw.c5
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw.h315
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw_quad.c26
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw_quad.h125
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_index_modify.c385
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_index_modify.h140
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_inlines.h37
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_pstipple.c3
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_slab.h174
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_string.h452
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_transfer.c8
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_transfer.h259
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_vbuf.c34
-rw-r--r--mesalib/src/glsl/Makefile.sources2
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp1
-rw-r--r--mesalib/src/glsl/ir_optimization.h1
-rw-r--r--mesalib/src/glsl/linker.cpp11
-rw-r--r--mesalib/src/glsl/lower_discard_flow.cpp144
-rw-r--r--mesalib/src/glsl/opt_discard_simplification.cpp205
-rw-r--r--mesalib/src/glsl/test_optpass.cpp2
-rw-r--r--mesalib/src/mesa/main/context.c6
-rw-r--r--mesalib/src/mesa/main/debug.c75
-rw-r--r--mesalib/src/mesa/main/drawpix.c12
-rw-r--r--mesalib/src/mesa/main/errors.c21
-rw-r--r--mesalib/src/mesa/main/fbobject.c20
-rw-r--r--mesalib/src/mesa/main/light.c2
-rw-r--r--mesalib/src/mesa/main/mtypes.h5
-rw-r--r--mesalib/src/mesa/main/teximage.h7
-rw-r--r--mesalib/src/mesa/main/texobj.c17
-rw-r--r--mesalib/src/mesa/main/uniform_query.cpp10
-rw-r--r--mesalib/src/mesa/main/version.c12
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_constbuf.c347
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.c53
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h16
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c240
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw_feedback.c32
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp8
-rw-r--r--mesalib/src/mesa/vbo/vbo_attrib_tmp.h58
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_api.c99
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c16
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_api.c57
43 files changed, 1838 insertions, 1702 deletions
diff --git a/mesalib/configs/autoconf.in b/mesalib/configs/autoconf.in
index eb6713ddf..3c8f4c1ee 100644
--- a/mesalib/configs/autoconf.in
+++ b/mesalib/configs/autoconf.in
@@ -219,3 +219,6 @@ MESA_LLVM = @MESA_LLVM@
LLVM_VERSION = @LLVM_VERSION@
HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@
+
+GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@
+GALLIUM_PIPE_LOADER_LIBS = @GALLIUM_PIPE_LOADER_LIBS@
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 3bc59ca3e..e177846d7 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -109,11 +109,11 @@ if test "x$GCC" = xyes -a "x$acv_mesa_CLANG" = xno; then
GCC_VERSION=`$CC -dumpversion`
if test $? -eq 0; then
- major=`echo $GCC_VERSION | cut -d. -f1`
- minor=`echo $GCC_VERSION | cut -d. -f2`
+ GCC_VERSION_MAJOR=`echo $GCC_VERSION | cut -d. -f1`
+ GCC_VERSION_MINOR=`echo $GCC_VERSION | cut -d. -f2`
fi
- if test $major -lt 3 -o $major -eq 3 -a $minor -lt 3 ; then
+ if test $GCC_VERSION_MAJOR -lt 3 -o $GCC_VERSION_MAJOR -eq 3 -a $GCC_VERSION_MINOR -lt 3 ; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([If using GCC, version 3.3.0 or later is required.])
else
@@ -616,7 +616,11 @@ AC_ARG_ENABLE([va],
[enable va library @<:@default=auto@:>@])],
[enable_va="$enableval"],
[enable_va=auto])
-
+AC_ARG_ENABLE([opencl],
+ [AS_HELP_STRING([--enable-opencl],
+ [enable OpenCL library @<:@default=no@:>@])],
+ [enable_opencl="$enableval"],
+ [enable_opencl=no])
AC_ARG_ENABLE([xlib_glx],
[AS_HELP_STRING([--enable-xlib-glx],
[make GLX library Xlib-based instead of DRI-based @<:@default=disable@:>@])],
@@ -643,6 +647,12 @@ AC_ARG_ENABLE([r600-llvm-compiler],
[enable_r600_llvm="$enableval"],
[enable_r600_llvm=no])
+AC_ARG_ENABLE([gallium_tests],
+ [AS_HELP_STRING([--enable-gallium-tests],
+ [Enable optional Gallium tests) @<:@default=disable@:>@])],
+ [enable_gallium_tests="$enableval"],
+ [enable_gallium_tests=no])
+
# Option for Gallium drivers
GALLIUM_DRIVERS_DEFAULT="r300,r600,svga,swrast"
@@ -670,7 +680,8 @@ if test "x$enable_opengl" = xno -a \
"x$enable_d3d1x" = xno -a \
"x$enable_xvmc" = xno -a \
"x$enable_vdpau" = xno -a \
- "x$enable_va" = xno; then
+ "x$enable_va" = xno -a \
+ "x$enable_opencl" = xno; then
AC_MSG_ERROR([at least one API should be enabled])
fi
@@ -1477,6 +1488,7 @@ if test "x$enable_gallium_gbm" = xyes; then
GALLIUM_STATE_TRACKERS_DIRS="gbm $GALLIUM_STATE_TRACKERS_DIRS"
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS gbm"
HAVE_ST_GBM="yes"
+ enable_gallium_loader=yes
fi
dnl
@@ -1597,6 +1609,24 @@ if test "x$enable_va" = xyes; then
fi
dnl
+dnl OpenCL configuration
+dnl
+
+if test "x$enable_opencl" = xyes; then
+ if test "x$with_gallium_drivers" = x; then
+ AC_MSG_ERROR([cannot enable OpenCL without Gallium])
+ fi
+
+ if test $GCC_VERSION_MAJOR -lt 4 -o $GCC_VERSION_MAJOR -eq 4 -a $GCC_VERSION_MINOR -lt 6; then
+ AC_MSG_ERROR([gcc >= 4.6 is required to build clover])
+ fi
+
+ GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS clover"
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS opencl"
+ enable_gallium_loader=yes
+fi
+
+dnl
dnl GLU configuration
dnl
AC_ARG_ENABLE([glu],
@@ -1828,6 +1858,14 @@ AC_ARG_WITH([xvmc-libdir],
[XVMC_LIB_INSTALL_DIR='${libdir}'])
AC_SUBST([XVMC_LIB_INSTALL_DIR])
+dnl
+dnl Gallium Tests
+dnl
+if test "x$enable_gallium_tests" = xyes; then
+ SRC_DIRS="$SRC_DIRS gallium/tests/trivial"
+ enable_gallium_loader=yes
+fi
+
dnl Directory for VDPAU libs
AC_ARG_WITH([vdpau-libdir],
[AS_HELP_STRING([--with-vdpau-libdir=DIR],
@@ -1844,6 +1882,14 @@ AC_ARG_WITH([va-libdir],
[VA_LIB_INSTALL_DIR='${libdir}/va'])
AC_SUBST([VA_LIB_INSTALL_DIR])
+dnl Directory for OpenCL libs
+AC_ARG_WITH([opencl-libdir],
+ [AS_HELP_STRING([--with-opencl-libdir=DIR],
+ [directory for the OpenCL libraries @<:@default=${libdir}/opencl@:>@])],
+ [OPENCL_LIB_INSTALL_DIR="$withval"],
+ [OPENCL_LIB_INSTALL_DIR='${libdir}/opencl'])
+AC_SUBST([OPENCL_LIB_INSTALL_DIR])
+
dnl
dnl Gallium helper functions
dnl
@@ -1884,6 +1930,17 @@ gallium_require_llvm() {
fi
}
+gallium_require_drm_loader() {
+ if test "x$enable_gallium_loader" = xyes; then
+ PKG_CHECK_MODULES([LIBUDEV], [libudev], [],
+ AC_MSG_ERROR([Gallium drm loader requrires libudev]))
+ if test "x$have_libdrm" != xyes; then
+ AC_MSG_ERROR([Gallium drm loader requires libdrm >= $LIBDRM_REQUIRED])
+ fi
+ enable_gallium_drm_loader=yes
+ fi
+}
+
dnl Gallium drivers
dnl Duplicates in GALLIUM_DRIVERS_DIRS are removed by sorting it after this block
if test "x$with_gallium_drivers" != x; then
@@ -1911,6 +1968,7 @@ if test "x$with_gallium_drivers" != x; then
;;
xr600)
PKG_CHECK_MODULES([RADEON], [libdrm_radeon >= $LIBDRM_RADEON_REQUIRED])
+ gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
if test "x$enable_r600_llvm" = xyes; then
if test "x$LLVM_VERSION" != "x3.1"; then
@@ -1922,6 +1980,8 @@ if test "x$with_gallium_drivers" != x; then
gallium_check_st "radeon/drm" "dri-r600" "xorg-r600" "" "xvmc-r600" "vdpau-r600" "va-r600"
;;
xradeonsi)
+ PKG_CHECK_MODULES([RADEON], [libdrm_radeon >= $LIBDRM_RADEON_REQUIRED])
+ gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi"
if test "x$LLVM_VERSION" != "x3.1"; then
AC_MSG_ERROR([LLVM 3.1 is required to build the radeonsi driver.])
@@ -1931,6 +1991,7 @@ if test "x$with_gallium_drivers" != x; then
;;
xnouveau)
PKG_CHECK_MODULES([NOUVEAU], [libdrm_nouveau >= $LIBDRM_NOUVEAU_REQUIRED])
+ gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv30 nv50 nvc0"
gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau" "vdpau-nouveau"
;;
@@ -1967,6 +2028,25 @@ if test "x$with_gallium_drivers" != x; then
done
fi
+if test "x$enable_gallium_loader" = xyes; then
+ GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/null"
+ GALLIUM_PIPE_LOADER_DEFINES="-DHAVE_PIPE_LOADER_SW"
+ GALLIUM_PIPE_LOADER_LIBS="\$(TOP)/src/gallium/auxiliary/pipe-loader/libpipe_loader.a"
+ GALLIUM_PIPE_LOADER_LIBS="$GALLIUM_PIPE_LOADER_LIBS \$(TOP)/src/gallium/winsys/sw/null/libws_null.a"
+
+ if test "x$HAVE_WINSYS_XLIB" = xyes; then
+ GALLIUM_PIPE_LOADER_DEFINES="$GALLIUM_PIPE_LOADER_DEFINES -DHAVE_PIPE_LOADER_XLIB"
+ GALLIUM_PIPE_LOADER_LIBS="$GALLIUM_PIPE_LOADER_LIBS \$(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a"
+ fi
+
+ if test "x$enable_gallium_drm_loader" = xyes; then
+ GALLIUM_PIPE_LOADER_DEFINES="$GALLIUM_PIPE_LOADER_DEFINES -DHAVE_PIPE_LOADER_DRM"
+ fi
+
+ AC_SUBST([GALLIUM_PIPE_LOADER_DEFINES])
+ AC_SUBST([GALLIUM_PIPE_LOADER_LIBS])
+fi
+
dnl Tell Automake which drivers to build
for driver in $GALLIUM_DRIVERS_DIRS; do
case "x$driver" in
@@ -1990,6 +2070,8 @@ AM_CONDITIONAL(HAVE_IDENTITY_GALLIUM, test x$HAVE_IDENTITY_GALLIUM = xyes)
AM_CONDITIONAL(HAVE_NOOP_GALLIUM, test x$HAVE_NOOP_GALLIUM = xyes)
AM_CONDITIONAL(NEED_RADEON_GALLIUM, test x$NEED_RADEON_GALLIUM = xyes)
AM_CONDITIONAL(USE_R600_LLVM_COMPILER, test x$USE_R600_LLVM_COMPILER = xyes)
+AM_CONDITIONAL(HAVE_LOADER_GALLIUM, test x$enable_gallium_loader = xyes)
+AM_CONDITIONAL(HAVE_DRM_LOADER_GALLIUM, test x$enable_gallium_drm_loader = xyes)
AC_SUBST([GALLIUM_MAKE_DIRS])
dnl prepend CORE_DIRS to SRC_DIRS
@@ -2005,9 +2087,12 @@ CXXFLAGS="$CXXFLAGS $USER_CXXFLAGS"
dnl Substitute the config
AC_CONFIG_FILES([configs/autoconf
+ src/gallium/auxiliary/pipe-loader/Makefile
+ src/gallium/state_trackers/clover/Makefile
src/gallium/drivers/Makefile
src/gallium/drivers/r300/Makefile
src/gallium/drivers/r600/Makefile
+ src/gallium/targets/opencl/Makefile
src/gbm/Makefile
src/gbm/main/gbm.pc
src/egl/drivers/Makefile
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.c b/mesalib/src/gallium/auxiliary/util/u_draw.c
index d16575b73..5b3c41231 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw.c
+++ b/mesalib/src/gallium/auxiliary/util/u_draw.c
@@ -44,7 +44,6 @@
unsigned
util_draw_max_index(
const struct pipe_vertex_buffer *vertex_buffers,
- unsigned nr_vertex_buffers,
const struct pipe_vertex_element *vertex_elements,
unsigned nr_vertex_elements,
const struct pipe_draw_info *info)
@@ -62,6 +61,10 @@ util_draw_max_index(
const struct util_format_description *format_desc;
unsigned format_size;
+ if (!buffer->buffer) {
+ continue;
+ }
+
assert(buffer->buffer->height0 == 1);
assert(buffer->buffer->depth0 == 1);
buffer_size = buffer->buffer->width0;
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.h b/mesalib/src/gallium/auxiliary/util/u_draw.h
index 69cf25aff..3dc69181c 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw.h
+++ b/mesalib/src/gallium/auxiliary/util/u_draw.h
@@ -1,158 +1,157 @@
-/**************************************************************************
- *
- * 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_DRAW_H
-#define U_DRAW_H
-
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-static INLINE void
-util_draw_init_info(struct pipe_draw_info *info)
-{
- memset(info, 0, sizeof(*info));
- info->instance_count = 1;
- info->max_index = 0xffffffff;
-}
-
-
-static INLINE void
-util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.min_index = start;
- info.max_index = start + count - 1;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_elements(struct pipe_context *pipe, int index_bias,
- uint mode, uint start, uint count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.indexed = TRUE;
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.index_bias = index_bias;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_arrays_instanced(struct pipe_context *pipe,
- uint mode, uint start, uint count,
- uint start_instance,
- uint instance_count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.start_instance = start_instance;
- info.instance_count = instance_count;
- info.min_index = start;
- info.max_index = start + count - 1;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_elements_instanced(struct pipe_context *pipe,
- int index_bias,
- uint mode, uint start, uint count,
- uint start_instance,
- uint instance_count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.indexed = TRUE;
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.index_bias = index_bias;
- info.start_instance = start_instance;
- info.instance_count = instance_count;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_range_elements(struct pipe_context *pipe,
- int index_bias,
- uint min_index,
- uint max_index,
- uint mode, uint start, uint count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.indexed = TRUE;
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.index_bias = index_bias;
- info.min_index = min_index;
- info.max_index = max_index;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-
-unsigned
-util_draw_max_index(
- const struct pipe_vertex_buffer *vertex_buffers,
- unsigned nr_vertex_buffers,
- const struct pipe_vertex_element *vertex_elements,
- unsigned nr_vertex_elements,
- const struct pipe_draw_info *info);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !U_DRAW_H */
+/**************************************************************************
+ *
+ * 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_DRAW_H
+#define U_DRAW_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+static INLINE void
+util_draw_init_info(struct pipe_draw_info *info)
+{
+ memset(info, 0, sizeof(*info));
+ info->instance_count = 1;
+ info->max_index = 0xffffffff;
+}
+
+
+static INLINE void
+util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count)
+{
+ struct pipe_draw_info info;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.min_index = start;
+ info.max_index = start + count - 1;
+
+ pipe->draw_vbo(pipe, &info);
+}
+
+static INLINE void
+util_draw_elements(struct pipe_context *pipe, int index_bias,
+ uint mode, uint start, uint count)
+{
+ struct pipe_draw_info info;
+
+ util_draw_init_info(&info);
+ info.indexed = TRUE;
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.index_bias = index_bias;
+
+ pipe->draw_vbo(pipe, &info);
+}
+
+static INLINE void
+util_draw_arrays_instanced(struct pipe_context *pipe,
+ uint mode, uint start, uint count,
+ uint start_instance,
+ uint instance_count)
+{
+ struct pipe_draw_info info;
+
+ util_draw_init_info(&info);
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.start_instance = start_instance;
+ info.instance_count = instance_count;
+ info.min_index = start;
+ info.max_index = start + count - 1;
+
+ pipe->draw_vbo(pipe, &info);
+}
+
+static INLINE void
+util_draw_elements_instanced(struct pipe_context *pipe,
+ int index_bias,
+ uint mode, uint start, uint count,
+ uint start_instance,
+ uint instance_count)
+{
+ struct pipe_draw_info info;
+
+ util_draw_init_info(&info);
+ info.indexed = TRUE;
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.index_bias = index_bias;
+ info.start_instance = start_instance;
+ info.instance_count = instance_count;
+
+ pipe->draw_vbo(pipe, &info);
+}
+
+static INLINE void
+util_draw_range_elements(struct pipe_context *pipe,
+ int index_bias,
+ uint min_index,
+ uint max_index,
+ uint mode, uint start, uint count)
+{
+ struct pipe_draw_info info;
+
+ util_draw_init_info(&info);
+ info.indexed = TRUE;
+ info.mode = mode;
+ info.start = start;
+ info.count = count;
+ info.index_bias = index_bias;
+ info.min_index = min_index;
+ info.max_index = max_index;
+
+ pipe->draw_vbo(pipe, &info);
+}
+
+
+unsigned
+util_draw_max_index(
+ const struct pipe_vertex_buffer *vertex_buffers,
+ const struct pipe_vertex_element *vertex_elements,
+ unsigned nr_vertex_elements,
+ const struct pipe_draw_info *info);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !U_DRAW_H */
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw_quad.c b/mesalib/src/gallium/auxiliary/util/u_draw_quad.c
index 590fa0c36..469c87498 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/mesalib/src/gallium/auxiliary/util/u_draw_quad.c
@@ -69,6 +69,27 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
}
+/**
+ * Draw a simple vertex buffer / primitive.
+ * Limited to float[4] vertex attribs, tightly packed.
+ */
+void
+util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer,
+ uint prim_type, uint num_verts, uint num_attribs)
+{
+ struct pipe_vertex_buffer vbuffer = {0};
+
+ assert(num_attribs <= PIPE_MAX_ATTRIBS);
+
+ vbuffer.user_buffer = buffer;
+ vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */
+
+ /* note: vertex elements already set by caller */
+
+ cso_set_vertex_buffers(cso, 1, &vbuffer);
+ cso_draw_arrays(cso, prim_type, 0, num_verts);
+}
+
/**
* Draw screen-aligned textured quad.
@@ -118,10 +139,11 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
v[28] = 0.0;
v[29] = 1.0;
- vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuf = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STAGING, vertexBytes);
if (!vbuf)
goto out;
+ pipe_buffer_write(pipe, vbuf, 0, vertexBytes, v);
util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw_quad.h b/mesalib/src/gallium/auxiliary/util/u_draw_quad.h
index 997bbf060..2834a4a81 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw_quad.h
+++ b/mesalib/src/gallium/auxiliary/util/u_draw_quad.h
@@ -1,61 +1,64 @@
-/**************************************************************************
- *
- * 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_DRAWQUAD_H
-#define U_DRAWQUAD_H
-
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_context.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct pipe_resource;
-struct cso_context;
-
-#include "util/u_draw.h"
-
-extern void
-util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso,
- struct pipe_resource *vbuf, uint offset,
- uint num_attribs, uint num_verts, uint prim_type);
-
-
-extern void
-util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
- float x0, float y0, float x1, float y1, float z);
-
-
-#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_DRAWQUAD_H
+#define U_DRAWQUAD_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_resource;
+struct cso_context;
+
+#include "util/u_draw.h"
+
+extern void
+util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso,
+ struct pipe_resource *vbuf, uint offset,
+ uint num_attribs, uint num_verts, uint prim_type);
+
+void
+util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer,
+ uint prim_type, uint num_verts, uint num_attribs);
+
+extern void
+util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
+ float x0, float y0, float x1, float y1, float z);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_index_modify.c b/mesalib/src/gallium/auxiliary/util/u_index_modify.c
index 38e9b3700..5e3fd463e 100644
--- a/mesalib/src/gallium/auxiliary/util/u_index_modify.c
+++ b/mesalib/src/gallium/auxiliary/util/u_index_modify.c
@@ -1,182 +1,203 @@
-/*
- * Copyright 2010 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
- * on 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 AUTHOR(S) AND/OR THEIR 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. */
-
-#include "pipe/p_context.h"
-#include "util/u_index_modify.h"
-#include "util/u_inlines.h"
-
-/* Ubyte indices. */
-
-void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start,
- unsigned count,
- void *out)
-{
- struct pipe_transfer *src_transfer;
- unsigned char *in_map;
- unsigned short *out_map = out;
- unsigned i;
-
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &src_transfer);
- in_map += start;
-
- for (i = 0; i < count; i++) {
- *out_map = (unsigned short)(*in_map + index_bias);
- in_map++;
- out_map++;
- }
-
- pipe_buffer_unmap(context, src_transfer);
-}
-
-void util_shorten_ubyte_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start,
- unsigned count)
-{
- struct pipe_resource* new_elts;
- unsigned short *out_map;
- struct pipe_transfer *dst_transfer;
-
- new_elts = pipe_buffer_create(context->screen,
- PIPE_BIND_INDEX_BUFFER,
- PIPE_USAGE_STATIC,
- 2 * count);
-
- out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE,
- &dst_transfer);
- util_shorten_ubyte_elts_to_userptr(context, *elts, index_bias,
- start, count, out_map);
- pipe_buffer_unmap(context, dst_transfer);
-
- *elts = new_elts;
-}
-
-
-/* Ushort indices. */
-
-void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out)
-{
- struct pipe_transfer *in_transfer = NULL;
- unsigned short *in_map;
- unsigned short *out_map = out;
- unsigned i;
-
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &in_transfer);
- in_map += start;
-
- for (i = 0; i < count; i++) {
- *out_map = (unsigned short)(*in_map + index_bias);
- in_map++;
- out_map++;
- }
-
- pipe_buffer_unmap(context, in_transfer);
-}
-
-void util_rebuild_ushort_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count)
-{
- struct pipe_transfer *out_transfer = NULL;
- struct pipe_resource *new_elts;
- unsigned short *out_map;
-
- new_elts = pipe_buffer_create(context->screen,
- PIPE_BIND_INDEX_BUFFER,
- PIPE_USAGE_STATIC,
- 2 * count);
-
- out_map = pipe_buffer_map(context, new_elts,
- PIPE_TRANSFER_WRITE, &out_transfer);
- util_rebuild_ushort_elts_to_userptr(context, *elts, index_bias,
- start, count, out_map);
- pipe_buffer_unmap(context, out_transfer);
-
- *elts = new_elts;
-}
-
-
-/* Uint indices. */
-
-void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out)
-{
- struct pipe_transfer *in_transfer = NULL;
- unsigned int *in_map;
- unsigned int *out_map = out;
- unsigned i;
-
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &in_transfer);
- in_map += start;
-
- for (i = 0; i < count; i++) {
- *out_map = (unsigned int)(*in_map + index_bias);
- in_map++;
- out_map++;
- }
-
- pipe_buffer_unmap(context, in_transfer);
-}
-
-void util_rebuild_uint_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count)
-{
- struct pipe_transfer *out_transfer = NULL;
- struct pipe_resource *new_elts;
- unsigned int *out_map;
-
- new_elts = pipe_buffer_create(context->screen,
- PIPE_BIND_INDEX_BUFFER,
- PIPE_USAGE_STATIC,
- 2 * count);
-
- out_map = pipe_buffer_map(context, new_elts,
- PIPE_TRANSFER_WRITE, &out_transfer);
- util_rebuild_uint_elts_to_userptr(context, *elts, index_bias,
- start, count, out_map);
- pipe_buffer_unmap(context, out_transfer);
-
- *elts = new_elts;
-}
+/*
+ * Copyright 2010 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
+ * on 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 AUTHOR(S) AND/OR THEIR 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. */
+
+#include "pipe/p_context.h"
+#include "util/u_index_modify.h"
+#include "util/u_inlines.h"
+
+/* Ubyte indices. */
+
+void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ int index_bias,
+ unsigned start,
+ unsigned count,
+ void *out)
+{
+ struct pipe_transfer *src_transfer = NULL;
+ const unsigned char *in_map;
+ unsigned short *out_map = out;
+ unsigned i;
+
+ if (ib->user_buffer) {
+ in_map = ib->user_buffer;
+ } else {
+ in_map = pipe_buffer_map(context, ib->buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &src_transfer);
+ }
+ in_map += start;
+
+ for (i = 0; i < count; i++) {
+ *out_map = (unsigned short)(*in_map + index_bias);
+ in_map++;
+ out_map++;
+ }
+
+ if (src_transfer)
+ pipe_buffer_unmap(context, src_transfer);
+}
+
+void util_shorten_ubyte_elts(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
+ int index_bias,
+ unsigned start,
+ unsigned count)
+{
+ struct pipe_resource* new_elts;
+ unsigned short *out_map;
+ struct pipe_transfer *dst_transfer;
+
+ new_elts = pipe_buffer_create(context->screen,
+ PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
+ 2 * count);
+
+ out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE,
+ &dst_transfer);
+ util_shorten_ubyte_elts_to_userptr(context, ib, index_bias,
+ start, count, out_map);
+ pipe_buffer_unmap(context, dst_transfer);
+
+ pipe_resource_reference(out_buf, NULL);
+ *out_buf = new_elts;
+}
+
+
+/* Ushort indices. */
+
+void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ int index_bias,
+ unsigned start, unsigned count,
+ void *out)
+{
+ struct pipe_transfer *in_transfer = NULL;
+ const unsigned short *in_map;
+ unsigned short *out_map = out;
+ unsigned i;
+
+ if (ib->user_buffer) {
+ in_map = ib->user_buffer;
+ } else {
+ in_map = pipe_buffer_map(context, ib->buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
+ }
+ in_map += start;
+
+ for (i = 0; i < count; i++) {
+ *out_map = (unsigned short)(*in_map + index_bias);
+ in_map++;
+ out_map++;
+ }
+
+ if (in_transfer)
+ pipe_buffer_unmap(context, in_transfer);
+}
+
+void util_rebuild_ushort_elts(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
+ int index_bias,
+ unsigned start, unsigned count)
+{
+ struct pipe_transfer *out_transfer = NULL;
+ struct pipe_resource *new_elts;
+ unsigned short *out_map;
+
+ new_elts = pipe_buffer_create(context->screen,
+ PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
+ 2 * count);
+
+ out_map = pipe_buffer_map(context, new_elts,
+ PIPE_TRANSFER_WRITE, &out_transfer);
+ util_rebuild_ushort_elts_to_userptr(context, ib, index_bias,
+ start, count, out_map);
+ pipe_buffer_unmap(context, out_transfer);
+
+ pipe_resource_reference(out_buf, NULL);
+ *out_buf = new_elts;
+}
+
+
+/* Uint indices. */
+
+void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ int index_bias,
+ unsigned start, unsigned count,
+ void *out)
+{
+ struct pipe_transfer *in_transfer = NULL;
+ const unsigned int *in_map;
+ unsigned int *out_map = out;
+ unsigned i;
+
+ if (ib->user_buffer) {
+ in_map = ib->user_buffer;
+ } else {
+ in_map = pipe_buffer_map(context, ib->buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
+ }
+ in_map += start;
+
+ for (i = 0; i < count; i++) {
+ *out_map = (unsigned int)(*in_map + index_bias);
+ in_map++;
+ out_map++;
+ }
+
+ if (in_transfer)
+ pipe_buffer_unmap(context, in_transfer);
+}
+
+void util_rebuild_uint_elts(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
+ int index_bias,
+ unsigned start, unsigned count)
+{
+ struct pipe_transfer *out_transfer = NULL;
+ struct pipe_resource *new_elts;
+ unsigned int *out_map;
+
+ new_elts = pipe_buffer_create(context->screen,
+ PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
+ 2 * count);
+
+ out_map = pipe_buffer_map(context, new_elts,
+ PIPE_TRANSFER_WRITE, &out_transfer);
+ util_rebuild_uint_elts_to_userptr(context, ib, index_bias,
+ start, count, out_map);
+ pipe_buffer_unmap(context, out_transfer);
+
+ pipe_resource_reference(out_buf, NULL);
+ *out_buf = new_elts;
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_index_modify.h b/mesalib/src/gallium/auxiliary/util/u_index_modify.h
index 3e5520b18..6afce50b9 100644
--- a/mesalib/src/gallium/auxiliary/util/u_index_modify.h
+++ b/mesalib/src/gallium/auxiliary/util/u_index_modify.h
@@ -1,68 +1,72 @@
-/*
- * Copyright 2010 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
- * on 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 AUTHOR(S) AND/OR THEIR 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 UTIL_INDEX_MODIFY_H
-#define UTIL_INDEX_MODIFY_H
-
-struct pipe_context;
-struct pipe_resource;
-
-void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start,
- unsigned count,
- void *out);
-
-void util_shorten_ubyte_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start,
- unsigned count);
-
-
-
-void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out);
-
-void util_rebuild_ushort_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count);
-
-
-
-void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out);
-
-void util_rebuild_uint_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count);
-
-#endif
+/*
+ * Copyright 2010 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
+ * on 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 AUTHOR(S) AND/OR THEIR 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 UTIL_INDEX_MODIFY_H
+#define UTIL_INDEX_MODIFY_H
+
+struct pipe_context;
+struct pipe_resource;
+struct pipe_index_buffer;
+
+void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ int index_bias,
+ unsigned start,
+ unsigned count,
+ void *out);
+
+void util_shorten_ubyte_elts(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
+ int index_bias,
+ unsigned start,
+ unsigned count);
+
+
+
+void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ int index_bias,
+ unsigned start, unsigned count,
+ void *out);
+
+void util_rebuild_ushort_elts(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
+ int index_bias,
+ unsigned start, unsigned count);
+
+
+
+void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ int index_bias,
+ unsigned start, unsigned count,
+ void *out);
+
+void util_rebuild_uint_elts(struct pipe_context *context,
+ struct pipe_index_buffer *ib,
+ struct pipe_resource **out_buf,
+ int index_bias,
+ unsigned start, unsigned count);
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h
index 49b4531db..2ec153c58 100644
--- a/mesalib/src/gallium/auxiliary/util/u_inlines.h
+++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h
@@ -233,14 +233,6 @@ pipe_buffer_create( struct pipe_screen *screen,
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,
@@ -376,6 +368,19 @@ pipe_buffer_write_nooverlap(struct pipe_context *pipe,
0, 0);
}
+static INLINE struct pipe_resource *
+pipe_buffer_create_with_data(struct pipe_context *pipe,
+ unsigned bind,
+ unsigned usage,
+ unsigned size,
+ void *ptr)
+{
+ struct pipe_resource *res = pipe_buffer_create(pipe->screen,
+ bind, usage, size);
+ pipe_buffer_write_nooverlap(pipe, res, 0, size, ptr);
+ return res;
+}
+
static INLINE void
pipe_buffer_read(struct pipe_context *pipe,
struct pipe_resource *buf,
@@ -437,6 +442,22 @@ pipe_transfer_destroy( struct pipe_context *context,
context->transfer_destroy(context, transfer);
}
+static INLINE void
+pipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
+ struct pipe_resource *buf)
+{
+ if (buf) {
+ struct pipe_constant_buffer cb;
+ cb.buffer = buf;
+ cb.buffer_offset = 0;
+ cb.buffer_size = buf->width0;
+ cb.user_buffer = NULL;
+ pipe->set_constant_buffer(pipe, shader, index, &cb);
+ } else {
+ pipe->set_constant_buffer(pipe, shader, index, NULL);
+ }
+}
+
static INLINE boolean util_get_offset(
const struct pipe_rasterizer_state *templ,
diff --git a/mesalib/src/gallium/auxiliary/util/u_pstipple.c b/mesalib/src/gallium/auxiliary/util/u_pstipple.c
index ac0df8c1a..3a91b1da1 100644
--- a/mesalib/src/gallium/auxiliary/util/u_pstipple.c
+++ b/mesalib/src/gallium/auxiliary/util/u_pstipple.c
@@ -298,12 +298,13 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
/* declare new position input reg */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
- decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR;
+ decl.Declaration.Interpolate = 1;
decl.Declaration.Semantic = 1;
decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
decl.Semantic.Index = 0;
decl.Range.First =
decl.Range.Last = wincoordInput;
+ decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR;
ctx->emit_declaration(ctx, &decl);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_slab.h b/mesalib/src/gallium/auxiliary/util/u_slab.h
index f49dca27d..3ed8b12d3 100644
--- a/mesalib/src/gallium/auxiliary/util/u_slab.h
+++ b/mesalib/src/gallium/auxiliary/util/u_slab.h
@@ -1,87 +1,87 @@
-/*
- * Copyright 2010 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
- * on 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 AUTHOR(S) AND/OR THEIR 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 slab allocator for equally sized memory allocations.
- * util_slab_alloc and util_slab_free have time complexity in O(1).
- *
- * Good for allocations which have very low lifetime and are allocated
- * and freed very often. Use a profiler first to know if it's worth using it!
- *
- * Candidates: get_transfer, user_buffer_create
- *
- * @author Marek Olšák
- */
-
-#ifndef U_SLAB_H
-#define U_SLAB_H
-
-#include "os/os_thread.h"
-
-enum util_slab_threading {
- UTIL_SLAB_SINGLETHREADED = FALSE,
- UTIL_SLAB_MULTITHREADED = TRUE
-};
-
-/* The page is an array of blocks (allocations). */
-struct util_slab_page {
- /* The header (linked-list pointers). */
- struct util_slab_page *prev, *next;
-
- /* Memory after the last member is dedicated to the page itself.
- * The allocated size is always larger than this structure. */
-};
-
-struct util_slab_mempool {
- /* Public members. */
- void *(*alloc)(struct util_slab_mempool *pool);
- void (*free)(struct util_slab_mempool *pool, void *ptr);
-
- /* Private members. */
- struct util_slab_block *first_free;
-
- struct util_slab_page list;
-
- unsigned block_size;
- unsigned page_size;
- unsigned num_blocks;
- unsigned num_pages;
- enum util_slab_threading threading;
-
- pipe_mutex mutex;
-};
-
-void util_slab_create(struct util_slab_mempool *pool,
- unsigned item_size,
- unsigned num_blocks,
- enum util_slab_threading threading);
-
-void util_slab_destroy(struct util_slab_mempool *pool);
-
-void util_slab_set_thread_safety(struct util_slab_mempool *pool,
- enum util_slab_threading threading);
-
-#define util_slab_alloc(pool) (pool)->alloc(pool)
-#define util_slab_free(pool, ptr) (pool)->free(pool, ptr)
-
-#endif
+/*
+ * Copyright 2010 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
+ * on 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 AUTHOR(S) AND/OR THEIR 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 slab allocator for equally sized memory allocations.
+ * util_slab_alloc and util_slab_free have time complexity in O(1).
+ *
+ * Good for allocations which have very low lifetime and are allocated
+ * and freed very often. Use a profiler first to know if it's worth using it!
+ *
+ * Candidates: get_transfer
+ *
+ * @author Marek Olšák
+ */
+
+#ifndef U_SLAB_H
+#define U_SLAB_H
+
+#include "os/os_thread.h"
+
+enum util_slab_threading {
+ UTIL_SLAB_SINGLETHREADED = FALSE,
+ UTIL_SLAB_MULTITHREADED = TRUE
+};
+
+/* The page is an array of blocks (allocations). */
+struct util_slab_page {
+ /* The header (linked-list pointers). */
+ struct util_slab_page *prev, *next;
+
+ /* Memory after the last member is dedicated to the page itself.
+ * The allocated size is always larger than this structure. */
+};
+
+struct util_slab_mempool {
+ /* Public members. */
+ void *(*alloc)(struct util_slab_mempool *pool);
+ void (*free)(struct util_slab_mempool *pool, void *ptr);
+
+ /* Private members. */
+ struct util_slab_block *first_free;
+
+ struct util_slab_page list;
+
+ unsigned block_size;
+ unsigned page_size;
+ unsigned num_blocks;
+ unsigned num_pages;
+ enum util_slab_threading threading;
+
+ pipe_mutex mutex;
+};
+
+void util_slab_create(struct util_slab_mempool *pool,
+ unsigned item_size,
+ unsigned num_blocks,
+ enum util_slab_threading threading);
+
+void util_slab_destroy(struct util_slab_mempool *pool);
+
+void util_slab_set_thread_safety(struct util_slab_mempool *pool,
+ enum util_slab_threading threading);
+
+#define util_slab_alloc(pool) (pool)->alloc(pool)
+#define util_slab_free(pool, ptr) (pool)->free(pool, ptr)
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_string.h b/mesalib/src/gallium/auxiliary/util/u_string.h
index 52e380698..ed15981f1 100644
--- a/mesalib/src/gallium/auxiliary/util/u_string.h
+++ b/mesalib/src/gallium/auxiliary/util/u_string.h
@@ -1,220 +1,232 @@
-/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-/**
- * @file
- * Platform independent functions for string manipulation.
- *
- * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-#ifndef U_STRING_H_
-#define U_STRING_H_
-
-#if !defined(WIN32) && !defined(XF86_LIBC_H)
-#include <stdio.h>
-#endif
-#include <stddef.h>
-#include <stdarg.h>
-
-#include "pipe/p_compiler.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef WIN32
-
-int util_vsnprintf(char *, size_t, const char *, va_list);
-int util_snprintf(char *str, size_t size, const char *format, ...);
-
-static INLINE void
-util_vsprintf(char *str, const char *format, va_list ap)
-{
- util_vsnprintf(str, (size_t)-1, format, ap);
-}
-
-static INLINE void
-util_sprintf(char *str, const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- util_vsnprintf(str, (size_t)-1, format, ap);
- va_end(ap);
-}
-
-static INLINE char *
-util_strchr(const char *s, char c)
-{
- while(*s) {
- if(*s == c)
- return (char *)s;
- ++s;
- }
- return NULL;
-}
-
-static INLINE char*
-util_strncat(char *dst, const char *src, size_t n)
-{
- char *p = dst + strlen(dst);
- const char *q = src;
- size_t i;
-
- for (i = 0; i < n && *q != '\0'; ++i)
- *p++ = *q++;
- *p = '\0';
-
- return dst;
-}
-
-static INLINE int
-util_strcmp(const char *s1, const char *s2)
-{
- unsigned char u1, u2;
-
- while (1) {
- u1 = (unsigned char) *s1++;
- u2 = (unsigned char) *s2++;
- if (u1 != u2)
- return u1 - u2;
- if (u1 == '\0')
- return 0;
- }
- return 0;
-}
-
-static INLINE int
-util_strncmp(const char *s1, const char *s2, size_t n)
-{
- unsigned char u1, u2;
-
- while (n-- > 0) {
- u1 = (unsigned char) *s1++;
- u2 = (unsigned char) *s2++;
- if (u1 != u2)
- return u1 - u2;
- if (u1 == '\0')
- return 0;
- }
- return 0;
-}
-
-static INLINE char *
-util_strstr(const char *haystack, const char *needle)
-{
- const char *p = haystack;
- size_t len = strlen(needle);
-
- for (; (p = util_strchr(p, *needle)) != 0; p++) {
- if (util_strncmp(p, needle, len) == 0) {
- return (char *)p;
- }
- }
- return NULL;
-}
-
-static INLINE void *
-util_memmove(void *dest, const void *src, size_t n)
-{
- char *p = (char *)dest;
- const char *q = (const char *)src;
- if (dest < src) {
- while (n--)
- *p++ = *q++;
- }
- else
- {
- p += n;
- q += n;
- while (n--)
- *--p = *--q;
- }
- return dest;
-}
-
-
-#else
-
-#define util_vsnprintf vsnprintf
-#define util_snprintf snprintf
-#define util_vsprintf vsprintf
-#define util_sprintf sprintf
-#define util_strchr strchr
-#define util_strcmp strcmp
-#define util_strncmp strncmp
-#define util_strncat strncat
-#define util_strstr strstr
-#define util_memmove memmove
-
-#endif
-
-
-/**
- * Printable string buffer
- */
-struct util_strbuf
-{
- char *str;
- char *ptr;
- size_t left;
-};
-
-
-static INLINE void
-util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size)
-{
- sbuf->str = str;
- sbuf->str[0] = 0;
- sbuf->ptr = sbuf->str;
- sbuf->left = size;
-}
-
-
-static INLINE void
-util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...)
-{
- if(sbuf->left > 1) {
- size_t written;
- va_list ap;
- va_start(ap, format);
- written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap);
- va_end(ap);
- sbuf->ptr += written;
- sbuf->left -= written;
- }
-}
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* U_STRING_H_ */
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Platform independent functions for string manipulation.
+ *
+ * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
+ */
+
+#ifndef U_STRING_H_
+#define U_STRING_H_
+
+#if !defined(WIN32) && !defined(XF86_LIBC_H)
+#include <stdio.h>
+#endif
+#include <stddef.h>
+#include <stdarg.h>
+
+#include "pipe/p_compiler.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _GNU_SOURCE
+
+#define util_strchrnul strchrnul
+
+#else
+
+static INLINE char *
+util_strchrnul(const char *s, char c)
+{
+ for (; *s && *s != c; ++s);
+
+ return (char *)s;
+}
+
+#endif
+
+#ifdef WIN32
+
+int util_vsnprintf(char *, size_t, const char *, va_list);
+int util_snprintf(char *str, size_t size, const char *format, ...);
+
+static INLINE void
+util_vsprintf(char *str, const char *format, va_list ap)
+{
+ util_vsnprintf(str, (size_t)-1, format, ap);
+}
+
+static INLINE void
+util_sprintf(char *str, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ util_vsnprintf(str, (size_t)-1, format, ap);
+ va_end(ap);
+}
+
+static INLINE char *
+util_strchr(const char *s, char c)
+{
+ char *p = util_strchrnul(s, c);
+
+ return *p ? p : NULL;
+}
+
+static INLINE char*
+util_strncat(char *dst, const char *src, size_t n)
+{
+ char *p = dst + strlen(dst);
+ const char *q = src;
+ size_t i;
+
+ for (i = 0; i < n && *q != '\0'; ++i)
+ *p++ = *q++;
+ *p = '\0';
+
+ return dst;
+}
+
+static INLINE int
+util_strcmp(const char *s1, const char *s2)
+{
+ unsigned char u1, u2;
+
+ while (1) {
+ u1 = (unsigned char) *s1++;
+ u2 = (unsigned char) *s2++;
+ if (u1 != u2)
+ return u1 - u2;
+ if (u1 == '\0')
+ return 0;
+ }
+ return 0;
+}
+
+static INLINE int
+util_strncmp(const char *s1, const char *s2, size_t n)
+{
+ unsigned char u1, u2;
+
+ while (n-- > 0) {
+ u1 = (unsigned char) *s1++;
+ u2 = (unsigned char) *s2++;
+ if (u1 != u2)
+ return u1 - u2;
+ if (u1 == '\0')
+ return 0;
+ }
+ return 0;
+}
+
+static INLINE char *
+util_strstr(const char *haystack, const char *needle)
+{
+ const char *p = haystack;
+ size_t len = strlen(needle);
+
+ for (; (p = util_strchr(p, *needle)) != 0; p++) {
+ if (util_strncmp(p, needle, len) == 0) {
+ return (char *)p;
+ }
+ }
+ return NULL;
+}
+
+static INLINE void *
+util_memmove(void *dest, const void *src, size_t n)
+{
+ char *p = (char *)dest;
+ const char *q = (const char *)src;
+ if (dest < src) {
+ while (n--)
+ *p++ = *q++;
+ }
+ else
+ {
+ p += n;
+ q += n;
+ while (n--)
+ *--p = *--q;
+ }
+ return dest;
+}
+
+
+#else
+
+#define util_vsnprintf vsnprintf
+#define util_snprintf snprintf
+#define util_vsprintf vsprintf
+#define util_sprintf sprintf
+#define util_strchr strchr
+#define util_strcmp strcmp
+#define util_strncmp strncmp
+#define util_strncat strncat
+#define util_strstr strstr
+#define util_memmove memmove
+
+#endif
+
+
+/**
+ * Printable string buffer
+ */
+struct util_strbuf
+{
+ char *str;
+ char *ptr;
+ size_t left;
+};
+
+
+static INLINE void
+util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size)
+{
+ sbuf->str = str;
+ sbuf->str[0] = 0;
+ sbuf->ptr = sbuf->str;
+ sbuf->left = size;
+}
+
+
+static INLINE void
+util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...)
+{
+ if(sbuf->left > 1) {
+ size_t written;
+ va_list ap;
+ va_start(ap, format);
+ written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap);
+ va_end(ap);
+ sbuf->ptr += written;
+ sbuf->left -= written;
+ }
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* U_STRING_H_ */
diff --git a/mesalib/src/gallium/auxiliary/util/u_transfer.c b/mesalib/src/gallium/auxiliary/util/u_transfer.c
index 673a984fc..0b2679ffd 100644
--- a/mesalib/src/gallium/auxiliary/util/u_transfer.c
+++ b/mesalib/src/gallium/auxiliary/util/u_transfer.c
@@ -125,11 +125,3 @@ void u_default_transfer_destroy(struct pipe_context *pipe,
{
FREE(transfer);
}
-
-void u_default_redefine_user_buffer(struct pipe_context *ctx,
- struct pipe_resource *resource,
- unsigned offset,
- unsigned size)
-{
- resource->width0 = MAX2(resource->width0, offset + size);
-}
diff --git a/mesalib/src/gallium/auxiliary/util/u_transfer.h b/mesalib/src/gallium/auxiliary/util/u_transfer.h
index 79e2d13a4..f4fdf9a48 100644
--- a/mesalib/src/gallium/auxiliary/util/u_transfer.h
+++ b/mesalib/src/gallium/auxiliary/util/u_transfer.h
@@ -1,132 +1,127 @@
-
-#ifndef U_TRANSFER_H
-#define U_TRANSFER_H
-
-/* Fallback implementations for inline read/writes which just go back
- * to the regular transfer behaviour.
- */
-#include "pipe/p_state.h"
-
-struct pipe_context;
-struct winsys_handle;
-
-boolean u_default_resource_get_handle(struct pipe_screen *screen,
- struct pipe_resource *resource,
- struct winsys_handle *handle);
-
-void u_default_transfer_inline_write( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride);
-
-void u_default_transfer_flush_region( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box);
-
-struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box);
-
-void u_default_transfer_unmap( struct pipe_context *pipe,
- struct pipe_transfer *transfer );
-
-void u_default_transfer_destroy(struct pipe_context *pipe,
- struct pipe_transfer *transfer);
-
-
-
-/* Useful helper to allow >1 implementation of resource functionality
- * to exist in a single driver. This is intended to be transitionary!
- */
-struct u_resource_vtbl {
-
- boolean (*resource_get_handle)(struct pipe_screen *,
- struct pipe_resource *tex,
- struct winsys_handle *handle);
-
- void (*resource_destroy)(struct pipe_screen *,
- struct pipe_resource *pt);
-
- struct pipe_transfer *(*get_transfer)(struct pipe_context *,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *);
-
- void (*transfer_destroy)(struct pipe_context *,
- struct pipe_transfer *);
-
- void *(*transfer_map)( struct pipe_context *,
- struct pipe_transfer *transfer );
-
- void (*transfer_flush_region)( struct pipe_context *,
- struct pipe_transfer *transfer,
- const struct pipe_box *);
-
- void (*transfer_unmap)( struct pipe_context *,
- struct pipe_transfer *transfer );
-
- void (*transfer_inline_write)( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride);
-};
-
-
-struct u_resource {
- struct pipe_resource b;
- const struct u_resource_vtbl *vtbl;
-};
-
-
-boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
- struct pipe_resource *resource,
- struct winsys_handle *handle);
-
-void u_resource_destroy_vtbl(struct pipe_screen *screen,
- struct pipe_resource *resource);
-
-struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box);
-
-void u_transfer_destroy_vtbl(struct pipe_context *pipe,
- struct pipe_transfer *transfer);
-
-void *u_transfer_map_vtbl( struct pipe_context *pipe,
- struct pipe_transfer *transfer );
-
-void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box);
-
-void u_transfer_unmap_vtbl( struct pipe_context *rm_ctx,
- struct pipe_transfer *transfer );
-
-void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride);
-
-void u_default_redefine_user_buffer(struct pipe_context *ctx,
- struct pipe_resource *resource,
- unsigned offset,
- unsigned size);
-
-#endif
+
+#ifndef U_TRANSFER_H
+#define U_TRANSFER_H
+
+/* Fallback implementations for inline read/writes which just go back
+ * to the regular transfer behaviour.
+ */
+#include "pipe/p_state.h"
+
+struct pipe_context;
+struct winsys_handle;
+
+boolean u_default_resource_get_handle(struct pipe_screen *screen,
+ struct pipe_resource *resource,
+ struct winsys_handle *handle);
+
+void u_default_transfer_inline_write( struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride);
+
+void u_default_transfer_flush_region( struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box);
+
+struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box);
+
+void u_default_transfer_unmap( struct pipe_context *pipe,
+ struct pipe_transfer *transfer );
+
+void u_default_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer);
+
+
+
+/* Useful helper to allow >1 implementation of resource functionality
+ * to exist in a single driver. This is intended to be transitionary!
+ */
+struct u_resource_vtbl {
+
+ boolean (*resource_get_handle)(struct pipe_screen *,
+ struct pipe_resource *tex,
+ struct winsys_handle *handle);
+
+ void (*resource_destroy)(struct pipe_screen *,
+ struct pipe_resource *pt);
+
+ struct pipe_transfer *(*get_transfer)(struct pipe_context *,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *);
+
+ void (*transfer_destroy)(struct pipe_context *,
+ struct pipe_transfer *);
+
+ void *(*transfer_map)( struct pipe_context *,
+ struct pipe_transfer *transfer );
+
+ void (*transfer_flush_region)( struct pipe_context *,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *);
+
+ void (*transfer_unmap)( struct pipe_context *,
+ struct pipe_transfer *transfer );
+
+ void (*transfer_inline_write)( struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride);
+};
+
+
+struct u_resource {
+ struct pipe_resource b;
+ const struct u_resource_vtbl *vtbl;
+};
+
+
+boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
+ struct pipe_resource *resource,
+ struct winsys_handle *handle);
+
+void u_resource_destroy_vtbl(struct pipe_screen *screen,
+ struct pipe_resource *resource);
+
+struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box);
+
+void u_transfer_destroy_vtbl(struct pipe_context *pipe,
+ struct pipe_transfer *transfer);
+
+void *u_transfer_map_vtbl( struct pipe_context *pipe,
+ struct pipe_transfer *transfer );
+
+void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box);
+
+void u_transfer_unmap_vtbl( struct pipe_context *rm_ctx,
+ struct pipe_transfer *transfer );
+
+void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride);
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf.c b/mesalib/src/gallium/auxiliary/util/u_vbuf.c
index 401c8a4a8..4141ba536 100644
--- a/mesalib/src/gallium/auxiliary/util/u_vbuf.c
+++ b/mesalib/src/gallium/auxiliary/util/u_vbuf.c
@@ -277,8 +277,8 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
uint8_t *map;
- if (vb->buffer->user_ptr) {
- map = vb->buffer->user_ptr + offset;
+ if (vb->user_buffer) {
+ map = (uint8_t*)vb->user_buffer + offset;
} else {
unsigned size = vb->stride ? num_vertices * vb->stride
: sizeof(double)*4;
@@ -307,10 +307,10 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
unsigned offset = ib->offset + start_index * ib->index_size;
uint8_t *map;
- assert(ib->buffer && ib->index_size);
+ assert((ib->buffer || ib->user_buffer) && ib->index_size);
- if (ib->buffer->user_ptr) {
- map = ib->buffer->user_ptr + offset;
+ if (ib->user_buffer) {
+ map = (uint8_t*)ib->user_buffer + offset;
} else {
map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset,
num_indices * ib->index_size,
@@ -713,15 +713,17 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i];
pipe_resource_reference(&orig_vb->buffer, vb->buffer);
+ orig_vb->user_buffer = vb->user_buffer;
real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset;
real_vb->stride = orig_vb->stride = vb->stride;
+ real_vb->user_buffer = NULL;
if (vb->stride) {
mgr->nonzero_stride_vb_mask |= 1 << i;
}
- if (!vb->buffer) {
+ if (!vb->buffer && !vb->user_buffer) {
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
}
@@ -733,13 +735,14 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
continue;
}
- if (!mgr->caps.user_vertex_buffers && vb->buffer->user_ptr) {
+ if (!mgr->caps.user_vertex_buffers && vb->user_buffer) {
mgr->user_vb_mask |= 1 << i;
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
}
pipe_resource_reference(&real_vb->buffer, vb->buffer);
+ real_vb->user_buffer = vb->user_buffer;
}
for (i = count; i < mgr->nr_vertex_buffers; i++) {
@@ -759,11 +762,10 @@ void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
{
struct pipe_context *pipe = mgr->pipe;
- if (ib && ib->buffer) {
+ if (ib) {
assert(ib->offset % ib->index_size == 0);
pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer);
- mgr->index_buffer.offset = ib->offset;
- mgr->index_buffer.index_size = ib->index_size;
+ memcpy(&mgr->index_buffer, ib, sizeof(*ib));
} else {
pipe_resource_reference(&mgr->index_buffer.buffer, NULL);
}
@@ -798,9 +800,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
continue;
}
- assert(vb->buffer);
-
- if (!vb->buffer->user_ptr) {
+ if (!vb->user_buffer) {
continue;
}
@@ -837,7 +837,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
for (i = 0; i < nr_vbufs; i++) {
unsigned start, end = end_offset[i];
struct pipe_vertex_buffer *real_vb;
- uint8_t *ptr;
+ const uint8_t *ptr;
if (!end) {
continue;
@@ -847,7 +847,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
assert(start < end);
real_vb = &mgr->real_vertex_buffer[i];
- ptr = mgr->vertex_buffer[i].buffer->user_ptr;
+ ptr = mgr->vertex_buffer[i].user_buffer;
u_upload_data(mgr->uploader, start, end - start, ptr + start,
&real_vb->buffer_offset, &real_vb->buffer);
@@ -888,8 +888,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
unsigned i;
unsigned restart_index = info->restart_index;
- if (ib->buffer->user_ptr) {
- indices = ib->buffer->user_ptr +
+ if (ib->user_buffer) {
+ indices = (uint8_t*)ib->user_buffer +
ib->offset + info->start * ib->index_size;
} else {
indices = pipe_buffer_map_range(pipe, ib->buffer,
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index 5621e42b2..fba03604c 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/src/glsl/Makefile.sources
@@ -51,6 +51,7 @@ LIBGLSL_CXX_FILES := \
loop_unroll.cpp \
lower_clip_distance.cpp \
lower_discard.cpp \
+ lower_discard_flow.cpp \
lower_if_to_cond_assign.cpp \
lower_instructions.cpp \
lower_jumps.cpp \
@@ -72,7 +73,6 @@ LIBGLSL_CXX_FILES := \
opt_dead_code.cpp \
opt_dead_code_local.cpp \
opt_dead_functions.cpp \
- opt_discard_simplification.cpp \
opt_function_inlining.cpp \
opt_if_simplification.cpp \
opt_noop_swizzle.cpp \
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 6f1c86b43..46f21dd07 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -1044,7 +1044,6 @@ do_common_optimization(exec_list *ir, bool linked,
progress = do_structure_splitting(ir) || progress;
}
progress = do_if_simplification(ir) || progress;
- progress = do_discard_simplification(ir) || progress;
progress = do_copy_propagation(ir) || progress;
progress = do_copy_propagation_elements(ir) || progress;
if (linked)
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index 356783583..c435d7717 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -66,6 +66,7 @@ bool do_tree_grafting(exec_list *instructions);
bool do_vec_index_to_cond_assign(exec_list *instructions);
bool do_vec_index_to_swizzle(exec_list *instructions);
bool lower_discard(exec_list *instructions);
+void lower_discard_flow(exec_list *instructions);
bool lower_instructions(exec_list *instructions, unsigned what_to_lower);
bool lower_noise(exec_list *instructions);
bool lower_variable_index_to_cond_assign(exec_list *instructions,
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 6ba297237..bdab499f0 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -2296,6 +2296,17 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
prog->LinkStatus = true;
}
+ /* Implement the GLSL 1.30+ rule for discard vs infinite loops Do
+ * it before optimization because we want most of the checks to get
+ * dropped thanks to constant propagation.
+ */
+ if (max_version >= 130) {
+ struct gl_shader *sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+ if (sh) {
+ lower_discard_flow(sh->ir);
+ }
+ }
+
/* Do common optimization before assigning storage for attributes,
* uniforms, and varyings. Later optimization could possibly make
* some of that unused.
diff --git a/mesalib/src/glsl/lower_discard_flow.cpp b/mesalib/src/glsl/lower_discard_flow.cpp
new file mode 100644
index 000000000..d385c1435
--- /dev/null
+++ b/mesalib/src/glsl/lower_discard_flow.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file lower_discard_flow.cpp
+ *
+ * Implements the GLSL 1.30 revision 9 rule for fragment shader
+ * discard handling:
+ *
+ * "Control flow exits the shader, and subsequent implicit or
+ * explicit derivatives are undefined when this control flow is
+ * non-uniform (meaning different fragments within the primitive
+ * take different control paths)."
+ *
+ * There seem to be two conflicting things here. "Control flow exits
+ * the shader" sounds like the discarded fragments should effectively
+ * jump to the end of the shader, but that breaks derivatives in the
+ * case of uniform control flow and causes rendering failure in the
+ * bushes in Unigine Tropics.
+ *
+ * The question, then, is whether the intent was "loops stop at the
+ * point that the only active channels left are discarded pixels" or
+ * "discarded pixels become inactive at the point that control flow
+ * returns to the top of a loop". This implements the second
+ * interpretation.
+ */
+
+#include "glsl_types.h"
+#include "ir.h"
+#include "program/hash_table.h"
+
+class lower_discard_flow_visitor : public ir_hierarchical_visitor {
+public:
+ lower_discard_flow_visitor(ir_variable *discarded)
+ : discarded(discarded)
+ {
+ mem_ctx = ralloc_parent(discarded);
+ }
+
+ ~lower_discard_flow_visitor()
+ {
+ }
+
+ ir_visitor_status visit_enter(ir_discard *ir);
+ ir_visitor_status visit_enter(ir_loop_jump *ir);
+ ir_visitor_status visit_enter(ir_loop *ir);
+ ir_visitor_status visit_enter(ir_function_signature *ir);
+
+ ir_if *generate_discard_break();
+
+ ir_variable *discarded;
+ void *mem_ctx;
+};
+
+ir_visitor_status
+lower_discard_flow_visitor::visit_enter(ir_loop_jump *ir)
+{
+ if (ir->mode != ir_loop_jump::jump_continue)
+ return visit_continue;
+
+ ir->insert_before(generate_discard_break());
+
+ return visit_continue;
+}
+
+ir_visitor_status
+lower_discard_flow_visitor::visit_enter(ir_discard *ir)
+{
+ ir_dereference *lhs = new(mem_ctx) ir_dereference_variable(discarded);
+ ir_rvalue *rhs = new(mem_ctx) ir_constant(true);
+ ir_assignment *assign = new(mem_ctx) ir_assignment(lhs, rhs);
+ ir->insert_before(assign);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+lower_discard_flow_visitor::visit_enter(ir_loop *ir)
+{
+ ir->body_instructions.push_tail(generate_discard_break());
+
+ return visit_continue;
+}
+
+ir_visitor_status
+lower_discard_flow_visitor::visit_enter(ir_function_signature *ir)
+{
+ if (strcmp(ir->function_name(), "main") != 0)
+ return visit_continue;
+
+ ir_dereference *lhs = new(mem_ctx) ir_dereference_variable(discarded);
+ ir_rvalue *rhs = new(mem_ctx) ir_constant(false);
+ ir_assignment *assign = new(mem_ctx) ir_assignment(lhs, rhs);
+ ir->body.push_head(assign);
+
+ return visit_continue;
+}
+
+ir_if *
+lower_discard_flow_visitor::generate_discard_break()
+{
+ ir_rvalue *if_condition = new(mem_ctx) ir_dereference_variable(discarded);
+ ir_if *if_inst = new(mem_ctx) ir_if(if_condition);
+
+ ir_instruction *br = new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break);
+ if_inst->then_instructions.push_tail(br);
+
+ return if_inst;
+}
+
+void
+lower_discard_flow(exec_list *ir)
+{
+ void *mem_ctx = ir;
+
+ ir_variable *var = new(mem_ctx) ir_variable(glsl_type::bool_type,
+ "discarded",
+ ir_var_temporary);
+
+ ir->push_head(var);
+
+ lower_discard_flow_visitor v(var);
+
+ visit_list_elements(&v, ir);
+}
diff --git a/mesalib/src/glsl/opt_discard_simplification.cpp b/mesalib/src/glsl/opt_discard_simplification.cpp
deleted file mode 100644
index ba4981bae..000000000
--- a/mesalib/src/glsl/opt_discard_simplification.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file opt_discard_simplification.cpp
- *
- * This pass simplifies if-statements and loops containing unconditional
- * discards.
- *
- * Case 1: Both branches contain unconditional discards:
- * -----------------------------------------------------
- *
- * if (cond) {
- * s1;
- * discard;
- * s2;
- * } else {
- * s3;
- * discard;
- * s4;
- * }
- *
- * becomes:
- *
- * discard
- *
- * Case 2: The "then" clause contains an unconditional discard:
- * ------------------------------------------------------------
- *
- * if (cond) {
- * s1;
- * discard;
- * s2;
- * } else {
- * s3;
- * }
- *
- * becomes:
- *
- * if (cond) {
- * discard;
- * } else {
- * s3;
- * }
- *
- * Case 3: The "else" clause contains an unconditional discard:
- * ------------------------------------------------------------
- *
- * if (cond) {
- * s1;
- * } else {
- * s2;
- * discard;
- * s3;
- * }
- *
- * becomes:
- *
- * if (cond) {
- * s1;
- * } else {
- * discard;
- * }
- */
-
-#include "glsl_types.h"
-#include "ir.h"
-
-class discard_simplifier : public ir_hierarchical_visitor {
-public:
- discard_simplifier()
- {
- this->progress = false;
- }
-
- ir_visitor_status visit_enter(ir_if *);
- ir_visitor_status visit_enter(ir_loop *);
- ir_visitor_status visit_enter(ir_assignment *);
-
- bool progress;
-};
-
-static ir_discard *
-find_unconditional_discard(exec_list &instructions)
-{
- foreach_list(n, &instructions) {
- ir_instruction *ir = (ir_instruction *)n;
-
- if (ir->ir_type == ir_type_return ||
- ir->ir_type == ir_type_loop_jump)
- return NULL;
-
- /* So far, this code doesn't know how to look inside of flow
- * control to see if a discard later on at this level is
- * unconditional.
- */
- if (ir->ir_type == ir_type_if ||
- ir->ir_type == ir_type_loop)
- return NULL;
-
- ir_discard *discard = ir->as_discard();
- if (discard != NULL && discard->condition == NULL)
- return discard;
- }
- return NULL;
-}
-
-static bool
-is_only_instruction(ir_discard *discard)
-{
- return (discard->prev->is_head_sentinel() &&
- discard->next->is_tail_sentinel());
-}
-
-/* We only care about the top level instructions, so don't descend
- * into expressions.
- */
-ir_visitor_status
-discard_simplifier::visit_enter(ir_assignment *ir)
-{
- (void) ir;
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-discard_simplifier::visit_enter(ir_if *ir)
-{
- ir_discard *then_discard = find_unconditional_discard(ir->then_instructions);
- ir_discard *else_discard = find_unconditional_discard(ir->else_instructions);
-
- if (then_discard == NULL && else_discard == NULL)
- return visit_continue;
-
- /* If both branches result in discard, replace whole if with discard. */
- if (then_discard != NULL && else_discard != NULL) {
- this->progress = true;
- ir->replace_with(then_discard);
- return visit_continue_with_parent;
- }
-
- /* Otherwise, one branch has a discard. */
- if (then_discard != NULL && !is_only_instruction(then_discard)) {
- this->progress = true;
- ir->then_instructions.make_empty();
- ir->then_instructions.push_tail(then_discard);
- } else if (else_discard != NULL && !is_only_instruction(else_discard)) {
- this->progress = true;
- ir->else_instructions.make_empty();
- ir->else_instructions.push_tail(else_discard);
- }
-
- visit_list_elements(this, &ir->then_instructions);
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-discard_simplifier::visit_enter(ir_loop *ir)
-{
- ir_discard *discard = find_unconditional_discard(ir->body_instructions);
-
- if (discard) {
- ir->replace_with(discard);
- return visit_continue_with_parent;
- }
-
- return visit_continue;
-}
-
-bool
-do_discard_simplification(exec_list *instructions)
-{
- /* Look for a top-level unconditional discard */
- ir_discard *discard = find_unconditional_discard(*instructions);
- if (discard != NULL) {
- instructions->make_empty();
- instructions->push_tail(discard);
- return true;
- }
-
- discard_simplifier v;
-
- visit_list_elements(&v, instructions);
-
- return v.progress;
-}
diff --git a/mesalib/src/glsl/test_optpass.cpp b/mesalib/src/glsl/test_optpass.cpp
index 6abafb5d3..31f65c3d2 100644
--- a/mesalib/src/glsl/test_optpass.cpp
+++ b/mesalib/src/glsl/test_optpass.cpp
@@ -98,8 +98,6 @@ do_optimization(struct exec_list *ir, const char *optimization)
return do_lower_texture_projection(ir);
} else if (strcmp(optimization, "do_if_simplification") == 0) {
return do_if_simplification(ir);
- } else if (strcmp(optimization, "do_discard_simplification") == 0) {
- return do_discard_simplification(ir);
} else if (sscanf(optimization, "lower_if_to_cond_assign ( %d ) ",
&int_0) == 1) {
return lower_if_to_cond_assign(ir, int_0);
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index 7e2ac98b9..bafd250a1 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -1635,6 +1635,7 @@ _mesa_record_error(struct gl_context *ctx, GLenum error)
void
_mesa_finish(struct gl_context *ctx)
{
+ FLUSH_VERTICES( ctx, 0 );
FLUSH_CURRENT( ctx, 0 );
if (ctx->Driver.Finish) {
ctx->Driver.Finish(ctx);
@@ -1648,6 +1649,7 @@ _mesa_finish(struct gl_context *ctx)
void
_mesa_flush(struct gl_context *ctx)
{
+ FLUSH_VERTICES( ctx, 0 );
FLUSH_CURRENT( ctx, 0 );
if (ctx->Driver.Flush) {
ctx->Driver.Flush(ctx);
@@ -1666,7 +1668,7 @@ void GLAPIENTRY
_mesa_Finish(void)
{
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
_mesa_finish(ctx);
}
@@ -1681,7 +1683,7 @@ void GLAPIENTRY
_mesa_Flush(void)
{
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
_mesa_flush(ctx);
}
diff --git a/mesalib/src/mesa/main/debug.c b/mesalib/src/mesa/main/debug.c
index f7b1f71f4..62b8e00c1 100644
--- a/mesalib/src/mesa/main/debug.c
+++ b/mesalib/src/mesa/main/debug.c
@@ -149,21 +149,19 @@ void _mesa_print_info( void )
/**
- * Set the debugging flags.
- *
- * \param debug debug string
- *
- * If compiled with debugging support then search for keywords in \p debug and
- * enables the verbose debug output of the respective feature.
+ * Set verbose logging flags. When these flags are set, GL API calls
+ * in the various categories will be printed to stderr.
+ * \param str a comma-separated list of keywords
*/
-static void add_debug_flags( const char *debug )
+static void
+set_verbose_flags(const char *str)
{
#ifdef DEBUG
- struct debug_option {
+ struct option {
const char *name;
GLbitfield flag;
};
- static const struct debug_option debug_opt[] = {
+ static const struct option opts[] = {
{ "varray", VERBOSE_VARRAY },
{ "tex", VERBOSE_TEXTURE },
{ "mat", VERBOSE_MATERIAL },
@@ -179,34 +177,59 @@ static void add_debug_flags( const char *debug )
};
GLuint i;
+ if (!str)
+ return;
+
MESA_VERBOSE = 0x0;
- for (i = 0; i < Elements(debug_opt); i++) {
- if (strstr(debug, debug_opt[i].name) || strcmp(debug, "all") == 0)
- MESA_VERBOSE |= debug_opt[i].flag;
+ for (i = 0; i < Elements(opts); i++) {
+ if (strstr(str, opts[i].name) || strcmp(str, "all") == 0)
+ MESA_VERBOSE |= opts[i].flag;
}
+#endif
+}
- /* Debug flag:
- */
- if (strstr(debug, "flush"))
- MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH;
-#else
- (void) debug;
+/**
+ * Set debugging flags. When these flags are set, Mesa will do additional
+ * debug checks or actions.
+ * \param str a comma-separated list of keywords
+ */
+static void
+set_debug_flags(const char *str)
+{
+#ifdef DEBUG
+ struct option {
+ const char *name;
+ GLbitfield flag;
+ };
+ static const struct option opts[] = {
+ { "silent", DEBUG_SILENT }, /* turn off debug messages */
+ { "flush", DEBUG_ALWAYS_FLUSH }, /* flush after each drawing command */
+ { "incomplete_tex", DEBUG_INCOMPLETE_TEXTURE },
+ { "incomplete_fbo", DEBUG_INCOMPLETE_FBO }
+ };
+ GLuint i;
+
+ if (!str)
+ return;
+
+ MESA_DEBUG_FLAGS = 0x0;
+ for (i = 0; i < Elements(opts); i++) {
+ if (strstr(str, opts[i].name))
+ MESA_DEBUG_FLAGS |= opts[i].flag;
+ }
#endif
}
+/**
+ * Initialize debugging variables from env vars.
+ */
void
_mesa_init_debug( struct gl_context *ctx )
{
- char *c;
- c = _mesa_getenv("MESA_DEBUG");
- if (c)
- add_debug_flags(c);
-
- c = _mesa_getenv("MESA_VERBOSE");
- if (c)
- add_debug_flags(c);
+ set_debug_flags(_mesa_getenv("MESA_DEBUG"));
+ set_verbose_flags(_mesa_getenv("MESA_VERBOSE"));
}
diff --git a/mesalib/src/mesa/main/drawpix.c b/mesalib/src/mesa/main/drawpix.c
index c2f7db2e8..def55dddd 100644
--- a/mesalib/src/mesa/main/drawpix.c
+++ b/mesalib/src/mesa/main/drawpix.c
@@ -180,6 +180,10 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
end:
_mesa_set_vp_override(ctx, GL_FALSE);
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
@@ -280,6 +284,10 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
end:
_mesa_set_vp_override(ctx, GL_FALSE);
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
@@ -354,6 +362,10 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
/* update raster position */
ctx->Current.RasterPos[0] += xmove;
ctx->Current.RasterPos[1] += ymove;
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c
index 4a187b7b0..69dbb65cf 100644
--- a/mesalib/src/mesa/main/errors.c
+++ b/mesalib/src/mesa/main/errors.c
@@ -802,21 +802,20 @@ output_if_debug(const char *prefixString, const char *outputString,
{
static int debug = -1;
- /* Check the MESA_DEBUG environment variable if it hasn't
- * been checked yet. We only have to check it once...
+ /* Init the local 'debug' var once.
+ * Note: the _mesa_init_debug() function should have been called
+ * by now so MESA_DEBUG_FLAGS will be initialized.
*/
if (debug == -1) {
- char *env = _mesa_getenv("MESA_DEBUG");
-
- /* In a debug build, we print warning messages *unless*
- * MESA_DEBUG is 0. In a non-debug build, we don't
- * print warning messages *unless* MESA_DEBUG is
- * set *to any value*.
- */
#ifdef DEBUG
- debug = (env != NULL && atoi(env) == 0) ? 0 : 1;
+ /* in debug builds, print messages unless MESA_DEBUG="silent" */
+ if (MESA_DEBUG_FLAGS & DEBUG_SILENT)
+ debug = 0;
+ else
+ debug = 1;
#else
- debug = (env != NULL) ? 1 : 0;
+ /* in release builds, be silent unless MESA_DEBUG is set */
+ debug = _mesa_getenv("MESA_DEBUG") != NULL;
#endif
}
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index f56369483..777783eb7 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -49,9 +49,6 @@
#include "texobj.h"
-/** Set this to 1 to help debug FBO incompleteness problems */
-#define DEBUG_FBO 0
-
/** Set this to 1 to debug/log glBlitFramebuffer() calls */
#define DEBUG_BLIT 0
@@ -462,11 +459,9 @@ _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
static void
att_incomplete(const char *msg)
{
-#if DEBUG_FBO
- _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
-#else
- (void) msg;
-#endif
+ if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
+ _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
+ }
}
@@ -476,12 +471,9 @@ att_incomplete(const char *msg)
static void
fbo_incomplete(const char *msg, int index)
{
-#if DEBUG_FBO
- _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
-#else
- (void) msg;
- (void) index;
-#endif
+ if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
+ _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
+ }
}
diff --git a/mesalib/src/mesa/main/light.c b/mesalib/src/mesa/main/light.c
index 7bc22e2fa..38ec1b6e8 100644
--- a/mesalib/src/mesa/main/light.c
+++ b/mesalib/src/mesa/main/light.c
@@ -728,6 +728,8 @@ _mesa_ColorMaterial( GLenum face, GLenum mode )
_mesa_lookup_enum_by_nr(mode));
bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");
+ if (bitmask == 0)
+ return; /* error was recorded */
if (ctx->Light.ColorMaterialBitmask == bitmask &&
ctx->Light.ColorMaterialFace == face &&
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 06ca0d5df..c306ac6b9 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -3522,7 +3522,10 @@ enum _verbose
/** The MESA_DEBUG_FLAGS var is a bitmask of these flags */
enum _debug
{
- DEBUG_ALWAYS_FLUSH = 0x1
+ DEBUG_SILENT = (1 << 0),
+ DEBUG_ALWAYS_FLUSH = (1 << 1),
+ DEBUG_INCOMPLETE_TEXTURE = (1 << 2),
+ DEBUG_INCOMPLETE_FBO = (1 << 3)
};
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index e2bdaca01..66a0c8895 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -35,6 +35,9 @@
#include "mtypes.h"
#include "formats.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
/** Is the given value one of the 6 cube faces? */
static inline GLboolean
@@ -287,4 +290,8 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
/*@}*/
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 155b255a7..365169ddd 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -410,16 +410,17 @@ static void
incomplete(struct gl_texture_object *t, enum base_mipmap bm,
const char *fmt, ...)
{
-#if 0
- va_list args;
- char s[100];
+ if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_TEXTURE) {
+ va_list args;
+ char s[100];
- va_start(args, fmt);
- vsnprintf(s, sizeof(s), fmt, args);
- va_end(args);
+ va_start(args, fmt);
+ vsnprintf(s, sizeof(s), fmt, args);
+ va_end(args);
+
+ _mesa_debug(NULL, "Texture Obj %d incomplete because: %s\n", t->Name, s);
+ }
- printf("Texture Obj %d incomplete because: %s\n", t->Name, s);
-#endif
if (bm == BASE)
t->_BaseComplete = GL_FALSE;
t->_MipmapComplete = GL_FALSE;
diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp
index da41ee84c..08d330a52 100644
--- a/mesalib/src/mesa/main/uniform_query.cpp
+++ b/mesalib/src/mesa/main/uniform_query.cpp
@@ -782,6 +782,16 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
return;
}
+ /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
+ * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml */
+ if (ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2) {
+ if (transpose) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glUniformMatrix(matrix transpose is not GL_FALSE)");
+ return;
+ }
+ }
+
if (ctx->Shader.Flags & GLSL_UNIFORMS) {
log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count,
bool(transpose), shProg, location, uni);
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index 09a930cf2..d2e34ca1e 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -259,7 +259,11 @@ compute_version_es1(struct gl_context *ctx)
ctx->VersionString = (char *) malloc(max);
if (ctx->VersionString) {
_mesa_snprintf(ctx->VersionString, max,
- "OpenGL ES-CM 1.%d Mesa " MESA_VERSION_STRING,
+ "OpenGL ES-CM 1.%d Mesa " MESA_VERSION_STRING
+#ifdef MESA_GIT_SHA1
+ " (" MESA_GIT_SHA1 ")"
+#endif
+ ,
ctx->VersionMinor);
}
}
@@ -289,7 +293,11 @@ compute_version_es2(struct gl_context *ctx)
ctx->VersionString = (char *) malloc(max);
if (ctx->VersionString) {
_mesa_snprintf(ctx->VersionString, max,
- "OpenGL ES 2.0 Mesa " MESA_VERSION_STRING);
+ "OpenGL ES 2.0 Mesa " MESA_VERSION_STRING
+#ifdef MESA_GIT_SHA1
+ " (" MESA_GIT_SHA1 ")"
+#endif
+ );
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
index 87a479a22..fd9228583 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
@@ -1,170 +1,177 @@
-/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Brian Paul
- */
-
-#include "main/imports.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-
-#include "st_debug.h"
-#include "st_context.h"
-#include "st_atom.h"
-#include "st_atom_constbuf.h"
-#include "st_program.h"
-
-
-/**
- * Pass the given program parameters to the graphics pipe as a
- * constant buffer.
- * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
- */
-void st_upload_constants( struct st_context *st,
- struct gl_program_parameter_list *params,
- unsigned shader_type)
-{
- struct pipe_context *pipe = st->pipe;
-
- assert(shader_type == PIPE_SHADER_VERTEX ||
- shader_type == PIPE_SHADER_FRAGMENT ||
- shader_type == PIPE_SHADER_GEOMETRY);
-
- /* update constants */
- if (params && params->NumParameters) {
- struct pipe_resource *cbuf;
- const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
-
- /* Update the constants which come from fixed-function state, such as
- * transformation matrices, fog factors, etc. The rest of the values in
- * the parameters list are explicitly set by the user with glUniform,
- * glProgramParameter(), etc.
- */
- _mesa_load_state_parameters(st->ctx, params);
-
- /* We always need to get a new buffer, to keep the drivers simple and
- * avoid gratuitous rendering synchronization.
- * Let's use a user buffer to avoid an unnecessary copy.
- */
- cbuf = pipe_user_buffer_create(pipe->screen,
- params->ParameterValues,
- paramBytes,
- PIPE_BIND_CONSTANT_BUFFER);
-
- if (ST_DEBUG & DEBUG_CONSTANTS) {
- debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
- __FUNCTION__, shader_type, params->NumParameters,
- params->StateFlags);
- _mesa_print_parameter_list(params);
- }
-
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf);
- pipe_resource_reference(&cbuf, NULL);
-
- st->state.constants[shader_type].ptr = params->ParameterValues;
- st->state.constants[shader_type].size = paramBytes;
- }
- else if (st->state.constants[shader_type].ptr) {
- st->state.constants[shader_type].ptr = NULL;
- st->state.constants[shader_type].size = 0;
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
- }
-}
-
-
-/**
- * Vertex shader:
- */
-static void update_vs_constants(struct st_context *st )
-{
- struct st_vertex_program *vp = st->vp;
- struct gl_program_parameter_list *params = vp->Base.Base.Parameters;
-
- st_upload_constants( st, params, PIPE_SHADER_VERTEX );
-}
-
-
-const struct st_tracked_state st_update_vs_constants = {
- "st_update_vs_constants", /* name */
- { /* dirty */
- (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
- ST_NEW_VERTEX_PROGRAM, /* st */
- },
- update_vs_constants /* update */
-};
-
-
-
-/**
- * Fragment shader:
- */
-static void update_fs_constants(struct st_context *st )
-{
- struct st_fragment_program *fp = st->fp;
- struct gl_program_parameter_list *params = fp->Base.Base.Parameters;
-
- st_upload_constants( st, params, PIPE_SHADER_FRAGMENT );
-}
-
-
-const struct st_tracked_state st_update_fs_constants = {
- "st_update_fs_constants", /* name */
- { /* dirty */
- (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
- ST_NEW_FRAGMENT_PROGRAM, /* st */
- },
- update_fs_constants /* update */
-};
-
-/* Geometry shader:
- */
-static void update_gs_constants(struct st_context *st )
-{
- struct st_geometry_program *gp = st->gp;
- struct gl_program_parameter_list *params;
-
- if (gp) {
- params = gp->Base.Base.Parameters;
- st_upload_constants( st, params, PIPE_SHADER_GEOMETRY );
- }
-}
-
-const struct st_tracked_state st_update_gs_constants = {
- "st_update_gs_constants", /* name */
- { /* dirty */
- (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
- ST_NEW_GEOMETRY_PROGRAM, /* st */
- },
- update_gs_constants /* update */
-};
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Brian Paul
+ */
+
+#include "main/imports.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+#include "util/u_upload_mgr.h"
+
+#include "st_debug.h"
+#include "st_context.h"
+#include "st_atom.h"
+#include "st_atom_constbuf.h"
+#include "st_program.h"
+
+
+/**
+ * Pass the given program parameters to the graphics pipe as a
+ * constant buffer.
+ * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
+ */
+void st_upload_constants( struct st_context *st,
+ struct gl_program_parameter_list *params,
+ unsigned shader_type)
+{
+ assert(shader_type == PIPE_SHADER_VERTEX ||
+ shader_type == PIPE_SHADER_FRAGMENT ||
+ shader_type == PIPE_SHADER_GEOMETRY);
+
+ /* update constants */
+ if (params && params->NumParameters) {
+ struct pipe_constant_buffer cb;
+ const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
+
+ /* Update the constants which come from fixed-function state, such as
+ * transformation matrices, fog factors, etc. The rest of the values in
+ * the parameters list are explicitly set by the user with glUniform,
+ * glProgramParameter(), etc.
+ */
+ _mesa_load_state_parameters(st->ctx, params);
+
+ /* We always need to get a new buffer, to keep the drivers simple and
+ * avoid gratuitous rendering synchronization.
+ * Let's use a user buffer to avoid an unnecessary copy.
+ */
+ if (st->constbuf_uploader) {
+ cb.buffer = NULL;
+ cb.user_buffer = NULL;
+ u_upload_data(st->constbuf_uploader, 0, paramBytes,
+ params->ParameterValues, &cb.buffer_offset, &cb.buffer);
+ u_upload_unmap(st->constbuf_uploader);
+ } else {
+ cb.buffer = NULL;
+ cb.user_buffer = params->ParameterValues;
+ cb.buffer_offset = 0;
+ }
+ cb.buffer_size = paramBytes;
+
+ if (ST_DEBUG & DEBUG_CONSTANTS) {
+ debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
+ __FUNCTION__, shader_type, params->NumParameters,
+ params->StateFlags);
+ _mesa_print_parameter_list(params);
+ }
+
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
+
+ st->state.constants[shader_type].ptr = params->ParameterValues;
+ st->state.constants[shader_type].size = paramBytes;
+ }
+ else if (st->state.constants[shader_type].ptr) {
+ st->state.constants[shader_type].ptr = NULL;
+ st->state.constants[shader_type].size = 0;
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
+ }
+}
+
+
+/**
+ * Vertex shader:
+ */
+static void update_vs_constants(struct st_context *st )
+{
+ struct st_vertex_program *vp = st->vp;
+ struct gl_program_parameter_list *params = vp->Base.Base.Parameters;
+
+ st_upload_constants( st, params, PIPE_SHADER_VERTEX );
+}
+
+
+const struct st_tracked_state st_update_vs_constants = {
+ "st_update_vs_constants", /* name */
+ { /* dirty */
+ (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
+ ST_NEW_VERTEX_PROGRAM, /* st */
+ },
+ update_vs_constants /* update */
+};
+
+
+
+/**
+ * Fragment shader:
+ */
+static void update_fs_constants(struct st_context *st )
+{
+ struct st_fragment_program *fp = st->fp;
+ struct gl_program_parameter_list *params = fp->Base.Base.Parameters;
+
+ st_upload_constants( st, params, PIPE_SHADER_FRAGMENT );
+}
+
+
+const struct st_tracked_state st_update_fs_constants = {
+ "st_update_fs_constants", /* name */
+ { /* dirty */
+ (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
+ ST_NEW_FRAGMENT_PROGRAM, /* st */
+ },
+ update_fs_constants /* update */
+};
+
+/* Geometry shader:
+ */
+static void update_gs_constants(struct st_context *st )
+{
+ struct st_geometry_program *gp = st->gp;
+ struct gl_program_parameter_list *params;
+
+ if (gp) {
+ params = gp->Base.Base.Parameters;
+ st_upload_constants( st, params, PIPE_SHADER_GEOMETRY );
+ }
+}
+
+const struct st_tracked_state st_update_gs_constants = {
+ "st_update_gs_constants", /* name */
+ { /* dirty */
+ (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
+ ST_NEW_GEOMETRY_PROGRAM, /* st */
+ },
+ update_gs_constants /* update */
+};
diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c
index ce7dbb3f3..b44976525 100644
--- a/mesalib/src/mesa/state_tracker/st_context.c
+++ b/mesalib/src/mesa/state_tracker/st_context.c
@@ -65,7 +65,6 @@
#include "util/u_inlines.h"
#include "util/u_upload_mgr.h"
#include "cso_cache/cso_context.h"
-#include "util/u_vbuf.h"
DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE)
@@ -112,32 +111,12 @@ st_get_msaa(void)
}
-static void st_init_vbuf(struct st_context *st)
-{
- struct u_vbuf_caps caps;
-
- u_vbuf_get_caps(st->pipe->screen, &caps);
-
- /* Create u_vbuf if there is anything unsupported. */
- if (!caps.buffer_offset_unaligned ||
- !caps.buffer_stride_unaligned ||
- !caps.velem_src_offset_unaligned ||
- !caps.format_fixed32 ||
- !caps.format_float16 ||
- !caps.format_float64 ||
- !caps.format_norm32 ||
- !caps.format_scaled32 ||
- !caps.user_vertex_buffers) {
- /* XXX user vertex buffers are always uploaded regardless of the CAP. */
- st->vbuf = u_vbuf_create(st->pipe, &caps);
- cso_install_vbuf(st->cso_context, st->vbuf);
- }
-}
static struct st_context *
st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
{
+ struct pipe_screen *screen = pipe->screen;
uint i;
struct st_context *st = ST_CALLOC_STRUCT( st_context );
@@ -156,9 +135,22 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
st->dirty.st = ~0;
st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
+
+ if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) {
+ st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4,
+ PIPE_BIND_INDEX_BUFFER);
+ }
+
+ if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) {
+ unsigned alignment =
+ screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT);
+
+ st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment,
+ PIPE_BIND_CONSTANT_BUFFER);
+ }
+
st->cso_context = cso_create_context(pipe);
- st_init_vbuf(st);
st_init_atoms( st );
st_init_bitmap(st);
st_init_clear(st);
@@ -254,11 +246,6 @@ static void st_destroy_context_priv( struct st_context *st )
st_destroy_drawpix(st);
st_destroy_drawtex(st);
- /* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_attribs; i++) {
- pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
- }
-
for (i = 0; i < Elements(st->state.sampler_views); i++) {
pipe_sampler_view_reference(&st->state.sampler_views[i], NULL);
}
@@ -269,6 +256,12 @@ static void st_destroy_context_priv( struct st_context *st )
}
u_upload_destroy(st->uploader);
+ if (st->indexbuf_uploader) {
+ u_upload_destroy(st->indexbuf_uploader);
+ }
+ if (st->constbuf_uploader) {
+ u_upload_destroy(st->constbuf_uploader);
+ }
free( st );
}
@@ -276,7 +269,6 @@ static void st_destroy_context_priv( struct st_context *st )
void st_destroy_context( struct st_context *st )
{
struct pipe_context *pipe = st->pipe;
- struct u_vbuf *vbuf = st->vbuf;
struct cso_context *cso = st->cso_context;
struct gl_context *ctx = st->ctx;
GLuint i;
@@ -312,9 +304,6 @@ void st_destroy_context( struct st_context *st )
st_destroy_context_priv(st);
st = NULL;
- if (vbuf)
- u_vbuf_destroy(vbuf);
-
cso_destroy_context(cso);
pipe->destroy( pipe );
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h
index 4786ed22f..00a405b69 100644
--- a/mesalib/src/mesa/state_tracker/st_context.h
+++ b/mesalib/src/mesa/state_tracker/st_context.h
@@ -41,7 +41,6 @@ struct gen_mipmap_state;
struct st_context;
struct st_fragment_program;
struct u_upload_mgr;
-struct u_vbuf;
#define ST_NEW_MESA (1 << 0) /* Mesa state has changed */
@@ -74,8 +73,7 @@ struct st_context
struct pipe_context *pipe;
- struct u_upload_mgr *uploader;
- struct u_vbuf *vbuf;
+ struct u_upload_mgr *uploader, *indexbuf_uploader, *constbuf_uploader;
struct draw_context *draw; /**< For selection/feedback/rastpos only */
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
@@ -191,18 +189,6 @@ struct st_context
int force_msaa;
void *winsys_drawable_handle;
- /* User vertex buffers. */
- struct {
- struct pipe_resource *buffer;
-
- /** Element size */
- GLuint element_size;
-
- /** Attribute stride */
- GLsizei stride;
- } user_attrib[PIPE_MAX_ATTRIBS];
- unsigned num_user_attribs;
-
/* Active render condition. */
struct pipe_query *render_condition;
unsigned condition_mode;
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index 42dc37576..a8c20f45a 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -61,6 +61,7 @@
#include "util/u_format.h"
#include "util/u_prim.h"
#include "util/u_draw_quad.h"
+#include "util/u_upload_mgr.h"
#include "draw/draw_context.h"
#include "cso_cache/cso_context.h"
@@ -402,18 +403,12 @@ setup_interleaved_attribs(struct gl_context *ctx,
const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer *vbuffer,
- struct pipe_vertex_element velements[],
- unsigned max_index,
- unsigned num_instances)
+ struct pipe_vertex_element velements[])
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
GLuint attr;
const GLubyte *low_addr = NULL;
GLboolean usingVBO; /* all arrays in a VBO? */
struct gl_buffer_object *bufobj;
- GLuint user_buffer_size = 0;
- GLuint vertex_size = 0; /* bytes per vertex, in bytes */
GLsizei stride;
/* Find the lowest address of the arrays we're drawing,
@@ -464,18 +459,6 @@ setup_interleaved_attribs(struct gl_context *ctx,
array->Normalized,
array->Integer);
assert(velements[attr].src_format);
-
- if (!usingVBO) {
- /* how many bytes referenced by this attribute array? */
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
- uint bytes = src_offset + stride * last_index + element_size;
-
- user_buffer_size = MAX2(user_buffer_size, bytes);
-
- /* update vertex size */
- vertex_size = MAX2(vertex_size, src_offset + element_size);
- }
}
/*
@@ -484,9 +467,9 @@ setup_interleaved_attribs(struct gl_context *ctx,
if (vpv->num_inputs == 0) {
/* just defensive coding here */
vbuffer->buffer = NULL;
+ vbuffer->user_buffer = NULL;
vbuffer->buffer_offset = 0;
vbuffer->stride = 0;
- st->num_user_attribs = 0;
}
else if (usingVBO) {
/* all interleaved arrays in a VBO */
@@ -497,26 +480,17 @@ setup_interleaved_attribs(struct gl_context *ctx,
return GL_FALSE;
}
- vbuffer->buffer = NULL;
- pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
+ vbuffer->buffer = stobj->buffer;
+ vbuffer->user_buffer = NULL;
vbuffer->buffer_offset = pointer_to_offset(low_addr);
vbuffer->stride = stride;
- st->num_user_attribs = 0;
}
else {
/* all interleaved arrays in user memory */
- vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
- (void*) low_addr,
- user_buffer_size,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffer->buffer = NULL;
+ vbuffer->user_buffer = low_addr;
vbuffer->buffer_offset = 0;
vbuffer->stride = stride;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
- st->user_attrib[0].element_size = vertex_size;
- st->user_attrib[0].stride = stride;
- st->num_user_attribs = 1;
}
return GL_TRUE;
@@ -536,22 +510,17 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer vbuffer[],
- struct pipe_vertex_element velements[],
- unsigned max_index,
- unsigned num_instances)
+ struct pipe_vertex_element velements[])
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
GLuint attr;
for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
const struct gl_client_array *array = arrays[mesaAttr];
struct gl_buffer_object *bufobj = array->BufferObj;
- GLuint element_size = array->_ElementSize;
GLsizei stride = array->StrideB;
- assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
+ assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type));
if (_mesa_is_bufferobj(bufobj)) {
/* Attribute data is in a VBO.
@@ -565,49 +534,28 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
return GL_FALSE;
}
- vbuffer[attr].buffer = NULL;
- pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer);
+ vbuffer[attr].buffer = stobj->buffer;
+ vbuffer[attr].user_buffer = NULL;
vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr);
}
else {
/* wrap user data */
- uint bytes;
void *ptr;
if (array->Ptr) {
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
-
- bytes = stride * last_index + element_size;
-
ptr = (void *) array->Ptr;
}
else {
/* no array, use ctx->Current.Attrib[] value */
- bytes = element_size = sizeof(ctx->Current.Attrib[0]);
ptr = (void *) ctx->Current.Attrib[mesaAttr];
stride = 0;
}
assert(ptr);
- assert(bytes);
-
- vbuffer[attr].buffer =
- pipe_user_buffer_create(pipe->screen, ptr, bytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffer[attr].buffer = NULL;
+ vbuffer[attr].user_buffer = ptr;
vbuffer[attr].buffer_offset = 0;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[attr].buffer, vbuffer[attr].buffer);
- st->user_attrib[attr].element_size = element_size;
- st->user_attrib[attr].stride = stride;
- st->num_user_attribs = MAX2(st->num_user_attribs, attr + 1);
-
- if (!vbuffer[attr].buffer) {
- /* probably ran out of memory */
- return GL_FALSE;
- }
}
/* common-case setup */
@@ -629,34 +577,31 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
static void
-setup_index_buffer(struct gl_context *ctx,
+setup_index_buffer(struct st_context *st,
const struct _mesa_index_buffer *ib,
struct pipe_index_buffer *ibuffer)
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
+ struct gl_buffer_object *bufobj = ib->obj;
- memset(ibuffer, 0, sizeof(*ibuffer));
- if (ib) {
- struct gl_buffer_object *bufobj = ib->obj;
-
- ibuffer->index_size = vbo_sizeof_ib_type(ib->type);
+ ibuffer->index_size = vbo_sizeof_ib_type(ib->type);
- /* get/create the index buffer object */
- if (_mesa_is_bufferobj(bufobj)) {
- /* elements/indexes are in a real VBO */
- struct st_buffer_object *stobj = st_buffer_object(bufobj);
- pipe_resource_reference(&ibuffer->buffer, stobj->buffer);
- ibuffer->offset = pointer_to_offset(ib->ptr);
- }
- else {
- /* element/indicies are in user space memory */
- ibuffer->buffer =
- pipe_user_buffer_create(pipe->screen, (void *) ib->ptr,
- ib->count * ibuffer->index_size,
- PIPE_BIND_INDEX_BUFFER);
- }
+ /* get/create the index buffer object */
+ if (_mesa_is_bufferobj(bufobj)) {
+ /* indices are in a real VBO */
+ ibuffer->buffer = st_buffer_object(bufobj)->buffer;
+ ibuffer->offset = pointer_to_offset(ib->ptr);
}
+ else if (st->indexbuf_uploader) {
+ u_upload_data(st->indexbuf_uploader, 0, ib->count * ibuffer->index_size,
+ ib->ptr, &ibuffer->offset, &ibuffer->buffer);
+ u_upload_unmap(st->indexbuf_uploader);
+ }
+ else {
+ /* indices are in user space memory */
+ ibuffer->user_buffer = ib->ptr;
+ }
+
+ cso_set_index_buffer(st->cso_context, ibuffer);
}
@@ -811,10 +756,10 @@ handle_fallback_primitive_restart(struct cso_context *cso,
unsigned num_sub_prims;
assert(info.indexed);
- assert(ibuffer->buffer);
+ assert(ibuffer->buffer || ibuffer->user_buffer);
assert(ib);
- if (!ibuffer->buffer || !ib)
+ if (!ibuffer->buffer || !ibuffer->user_buffer || !ib)
return;
info.primitive_restart = FALSE;
@@ -894,9 +839,7 @@ translate_prim(const struct gl_context *ctx, unsigned prim)
*/
static GLboolean
st_validate_varrays(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- unsigned max_index,
- unsigned num_instances)
+ const struct gl_client_array **arrays)
{
struct st_context *st = st_context(ctx);
const struct st_vertex_program *vp;
@@ -904,8 +847,6 @@ st_validate_varrays(struct gl_context *ctx,
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
unsigned num_vbuffers, num_velements;
- GLuint attr;
- unsigned i;
/* must get these after state validation! */
vp = st->vp;
@@ -913,18 +854,12 @@ st_validate_varrays(struct gl_context *ctx,
memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs);
- /* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_attribs; i++) {
- pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
- }
- st->num_user_attribs = 0;
-
/*
* Setup the vbuffer[] and velements[] arrays.
*/
if (is_interleaved_arrays(vp, vpv, arrays)) {
- if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements,
- max_index, num_instances)) {
+ if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer,
+ velements)) {
return GL_FALSE;
}
@@ -935,8 +870,7 @@ st_validate_varrays(struct gl_context *ctx,
}
else {
if (!setup_non_interleaved_attribs(ctx, vp, vpv, arrays,
- vbuffer, velements, max_index,
- num_instances)) {
+ vbuffer, velements)) {
return GL_FALSE;
}
@@ -947,14 +881,6 @@ st_validate_varrays(struct gl_context *ctx,
cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer);
cso_set_vertex_elements(st->cso_context, num_velements, velements);
- /* unreference buffers (frees wrapped user-space buffer objects)
- * This is OK, because the pipe driver should reference buffers by itself
- * in set_vertex_buffers. */
- for (attr = 0; attr < num_vbuffers; attr++) {
- pipe_resource_reference(&vbuffer[attr].buffer, NULL);
- assert(!vbuffer[attr].buffer);
- }
-
return GL_TRUE;
}
@@ -976,11 +902,10 @@ st_draw_vbo(struct gl_context *ctx,
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- struct pipe_index_buffer ibuffer;
+ struct pipe_index_buffer ibuffer = {0};
struct pipe_draw_info info;
const struct gl_client_array **arrays = ctx->Array._DrawArrays;
- unsigned i, num_instances = 1;
- unsigned max_index_plus_base;
+ unsigned i;
GLboolean new_array;
/* Mesa core state should have been validated already */
@@ -994,43 +919,6 @@ st_draw_vbo(struct gl_context *ctx,
(st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) ||
(st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;
- if (ib) {
- int max_base_vertex = 0;
-
- /* Gallium probably doesn't want this in some cases. */
- if (!index_bounds_valid)
- if (!all_varyings_in_vbos(arrays))
- vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
- nr_prims);
-
- for (i = 0; i < nr_prims; i++) {
- num_instances = MAX2(num_instances, prims[i].num_instances);
- max_base_vertex = MAX2(max_base_vertex, prims[i].basevertex);
- }
-
- /* Compute the sum of max_index and max_base_vertex. That's the value
- * we need to use when creating buffers.
- */
- if (max_index == ~0)
- max_index_plus_base = max_index;
- else
- max_index_plus_base = max_index + max_base_vertex;
- }
- else {
- /* Get min/max index for non-indexed drawing. */
- min_index = ~0;
- max_index = 0;
-
- for (i = 0; i < nr_prims; i++) {
- min_index = MIN2(min_index, prims[i].start);
- max_index = MAX2(max_index, prims[i].start + prims[i].count - 1);
- num_instances = MAX2(num_instances, prims[i].num_instances);
- }
-
- /* The base vertex offset only applies to indexed drawing */
- max_index_plus_base = max_index;
- }
-
/* Validate state. */
if (st->dirty.st) {
GLboolean vertDataEdgeFlags;
@@ -1045,8 +933,7 @@ st_draw_vbo(struct gl_context *ctx,
st_validate_state(st);
if (new_array) {
- if (!st_validate_varrays(ctx, arrays, max_index_plus_base,
- num_instances)) {
+ if (!st_validate_varrays(ctx, arrays)) {
/* probably out of memory, no-op the draw call */
return;
}
@@ -1061,31 +948,16 @@ st_draw_vbo(struct gl_context *ctx,
#endif
}
- /* Notify the driver that the content of user buffers may have been
- * changed. */
- assert(max_index >= min_index);
- if (!new_array && st->num_user_attribs) {
- for (i = 0; i < st->num_user_attribs; i++) {
- if (st->user_attrib[i].buffer) {
- unsigned element_size = st->user_attrib[i].element_size;
- unsigned stride = st->user_attrib[i].stride;
- unsigned min_offset = min_index * stride;
- unsigned max_offset = max_index_plus_base * stride + element_size;
-
- assert(max_offset > min_offset);
-
- pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer,
- min_offset,
- max_offset - min_offset);
- }
- }
- }
-
- setup_index_buffer(ctx, ib, &ibuffer);
- cso_set_index_buffer(st->cso_context, &ibuffer);
-
util_draw_init_info(&info);
if (ib) {
+ /* Get index bounds for user buffers. */
+ if (!index_bounds_valid)
+ if (!all_varyings_in_vbos(arrays))
+ vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
+ nr_prims);
+
+ setup_index_buffer(st, ib, &ibuffer);
+
info.indexed = TRUE;
if (min_index != ~0 && max_index != ~0) {
info.min_index = min_index;
@@ -1098,10 +970,12 @@ st_draw_vbo(struct gl_context *ctx,
info.primitive_restart = ctx->Array.PrimitiveRestart;
info.restart_index = ctx->Array.RestartIndex;
}
-
- /* Set info.count_from_stream_output. */
- if (tfb_vertcount) {
- st_transform_feedback_draw_init(tfb_vertcount, &info);
+ else {
+ /* Transform feedback drawing is always non-indexed. */
+ /* Set info.count_from_stream_output. */
+ if (tfb_vertcount) {
+ st_transform_feedback_draw_init(tfb_vertcount, &info);
+ }
}
/* do actual drawing */
@@ -1134,7 +1008,9 @@ st_draw_vbo(struct gl_context *ctx,
cso_draw_vbo(st->cso_context, &info);
}
- pipe_resource_reference(&ibuffer.buffer, NULL);
+ if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) {
+ pipe_resource_reference(&ibuffer.buffer, NULL);
+ }
}
diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
index 257618aa9..4209fb214 100644
--- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c
+++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
@@ -107,7 +107,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS];
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer ibuffer;
- struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+ struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL};
struct pipe_transfer *ib_transfer = NULL;
const struct gl_client_array **arrays = ctx->Array._DrawArrays;
GLuint attr, i;
@@ -169,23 +169,24 @@ st_feedback_draw_vbo(struct gl_context *ctx,
assert(stobj->buffer);
vbuffers[attr].buffer = NULL;
+ vbuffers[attr].user_buffer = NULL;
pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer);
vbuffers[attr].buffer_offset = pointer_to_offset(low_addr);
velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr;
+
+ /* map the attrib buffer */
+ map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
+ PIPE_TRANSFER_READ,
+ &vb_transfer[attr]);
+ draw_set_mapped_vertex_buffer(draw, attr, map);
}
else {
- /* attribute data is in user-space memory, not a VBO */
- uint bytes = (arrays[mesaAttr]->Size
- * _mesa_sizeof_type(arrays[mesaAttr]->Type)
- * (max_index + 1));
-
- /* wrap user data */
- vbuffers[attr].buffer
- = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr,
- bytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffers[attr].buffer = NULL;
+ vbuffers[attr].user_buffer = arrays[mesaAttr]->Ptr;
vbuffers[attr].buffer_offset = 0;
velements[attr].src_offset = 0;
+
+ draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer);
}
/* common-case setup */
@@ -204,12 +205,6 @@ st_feedback_draw_vbo(struct gl_context *ctx,
#if 0
draw_set_vertex_buffer(draw, attr, &vbuffer[attr]);
#endif
-
- /* map the attrib buffer */
- map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
- PIPE_TRANSFER_READ,
- &vb_transfer[attr]);
- draw_set_mapped_vertex_buffer(draw, attr, map);
}
draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers);
@@ -267,7 +262,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
out_unref_vertex:
for (attr = 0; attr < vp->num_inputs; attr++) {
- pipe_buffer_unmap(pipe, vb_transfer[attr]);
+ if (vb_transfer[attr])
+ pipe_buffer_unmap(pipe, vb_transfer[attr]);
draw_set_mapped_vertex_buffer(draw, attr, NULL);
pipe_resource_reference(&vbuffers[attr].buffer, NULL);
}
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 eecabb3e6..60a4e2831 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -3961,7 +3961,7 @@ dst_register(struct st_translate *t,
case PROGRAM_TEMPORARY:
if (ureg_dst_is_undef(t->temps[index]))
- t->temps[index] = ureg_DECL_temporary(t->ureg);
+ t->temps[index] = ureg_DECL_local_temporary(t->ureg);
return t->temps[index];
@@ -4002,7 +4002,7 @@ src_register(struct st_translate *t,
assert(index >= 0);
assert(index < Elements(t->temps));
if (ureg_dst_is_undef(t->temps[index]))
- t->temps[index] = ureg_DECL_temporary(t->ureg);
+ t->temps[index] = ureg_DECL_local_temporary(t->ureg);
return ureg_src(t->temps[index]);
case PROGRAM_NAMED_PARAM:
@@ -4259,7 +4259,7 @@ emit_wpos_adjustment( struct st_translate *t,
* or not, which is determined by testing against the inversion
* state variable used below, which will be either +1 or -1.
*/
- struct ureg_dst adj_temp = ureg_DECL_temporary(ureg);
+ struct ureg_dst adj_temp = ureg_DECL_local_temporary(ureg);
ureg_CMP(ureg, adj_temp,
ureg_scalar(wpostrans, invert ? 2 : 0),
@@ -4622,7 +4622,7 @@ st_translate_program(
*/
for (i = 0; i < (unsigned)program->next_temp; i++) {
/* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */
- t->temps[i] = ureg_DECL_temporary(t->ureg);
+ t->temps[i] = ureg_DECL_local_temporary(t->ureg);
}
}
diff --git a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
index 0bf5c9165..d3fc77eef 100644
--- a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
+++ b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
@@ -792,63 +792,6 @@ TAG(VertexAttrib4fvNV)(GLuint index, const GLfloat * v)
}
-
-#define MAT( ATTR, N, face, params ) \
-do { \
- if (face != GL_BACK) \
- MAT_ATTR( ATTR, N, params ); /* front */ \
- if (face != GL_FRONT) \
- MAT_ATTR( ATTR + 1, N, params ); /* back */ \
-} while (0)
-
-
-/* Colormaterial conflicts are dealt with later.
- */
-static void GLAPIENTRY
-TAG(Materialfv)(GLenum face, GLenum pname,
- const GLfloat * params)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glMaterial(invalid face)");
- return;
- }
-
- switch (pname) {
- case GL_EMISSION:
- MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params);
- break;
- case GL_AMBIENT:
- MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
- break;
- case GL_DIFFUSE:
- MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
- break;
- case GL_SPECULAR:
- MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params);
- break;
- case GL_SHININESS:
- if (*params < 0 || *params > ctx->Const.MaxShininess)
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glMaterial(invalid shininess: %f out range [0, %f])",
- *params, ctx->Const.MaxShininess);
- else
- MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params);
- break;
- case GL_COLOR_INDEXES:
- MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params);
- break;
- case GL_AMBIENT_AND_DIFFUSE:
- MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
- MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
- break;
- default:
- ERROR(GL_INVALID_ENUM);
- return;
- }
-}
-
static void GLAPIENTRY
TAG(VertexP2ui)(GLenum type, GLuint value)
{
@@ -1145,4 +1088,3 @@ TAG(VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized,
#undef ATTR_UI
#undef MAT
-#undef MAT_ATTR
diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c
index b87da18f3..28d2c4de9 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_api.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_api.c
@@ -433,6 +433,101 @@ do { \
#include "vbo_attrib_tmp.h"
+
+/**
+ * Execute a glMaterial call. Note that if GL_COLOR_MATERIAL is enabled,
+ * this may be a (partial) no-op.
+ */
+static void GLAPIENTRY
+vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ GLbitfield updateMats;
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* This function should be a no-op when it tries to update material
+ * attributes which are currently tracking glColor via glColorMaterial.
+ * The updateMats var will be a mask of the MAT_BIT_FRONT/BACK_x bits
+ * indicating which material attributes can actually be updated below.
+ */
+ if (ctx->Light.ColorMaterialEnabled) {
+ updateMats = ~ctx->Light.ColorMaterialBitmask;
+ }
+ else {
+ /* GL_COLOR_MATERIAL is disabled so don't skip any material updates */
+ updateMats = ALL_MATERIAL_BITS;
+ }
+
+ if (face == GL_FRONT) {
+ updateMats &= FRONT_MATERIAL_BITS;
+ }
+ else if (face == GL_BACK) {
+ updateMats &= BACK_MATERIAL_BITS;
+ }
+ else if (face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glMaterial(invalid face)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_EMISSION:
+ if (updateMats & MAT_BIT_FRONT_EMISSION)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, params);
+ if (updateMats & MAT_BIT_BACK_EMISSION)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_EMISSION, 4, params);
+ break;
+ case GL_AMBIENT:
+ if (updateMats & MAT_BIT_FRONT_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params);
+ if (updateMats & MAT_BIT_BACK_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params);
+ break;
+ case GL_DIFFUSE:
+ if (updateMats & MAT_BIT_FRONT_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params);
+ if (updateMats & MAT_BIT_BACK_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params);
+ break;
+ case GL_SPECULAR:
+ if (updateMats & MAT_BIT_FRONT_SPECULAR)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, params);
+ if (updateMats & MAT_BIT_BACK_SPECULAR)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_SPECULAR, 4, params);
+ break;
+ case GL_SHININESS:
+ if (*params < 0 || *params > ctx->Const.MaxShininess) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glMaterial(invalid shininess: %f out range [0, %f])",
+ *params, ctx->Const.MaxShininess);
+ return;
+ }
+ if (updateMats & MAT_BIT_FRONT_SHININESS)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, params);
+ if (updateMats & MAT_BIT_BACK_SHININESS)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_SHININESS, 1, params);
+ break;
+ case GL_COLOR_INDEXES:
+ if (updateMats & MAT_BIT_FRONT_INDEXES)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, params);
+ if (updateMats & MAT_BIT_BACK_INDEXES)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_INDEXES, 3, params);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ if (updateMats & MAT_BIT_FRONT_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params);
+ if (updateMats & MAT_BIT_FRONT_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params);
+ if (updateMats & MAT_BIT_BACK_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params);
+ if (updateMats & MAT_BIT_BACK_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params);
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glMaterialfv(pname)");
+ return;
+ }
+}
+
+
/**
* Flush (draw) vertices.
* \param unmap - leave VBO unmapped after flushing?
@@ -767,6 +862,10 @@ static void GLAPIENTRY vbo_exec_End( void )
}
else
_mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index cc94e761b..9303ad719 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -614,6 +614,10 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
GL_TRUE, start, start + count - 1,
NULL);
}
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
@@ -803,6 +807,10 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims( ctx, prim, 1, &ib,
index_bounds_valid, start, end, NULL );
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
@@ -1127,6 +1135,10 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
}
free(prim);
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
@@ -1201,6 +1213,10 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, prim, 1, NULL,
GL_TRUE, 0, 0, obj);
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
+ _mesa_flush(ctx);
+ }
}
/**
diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c
index 74f5dc9ce..f202375ca 100644
--- a/mesalib/src/mesa/vbo/vbo_save_api.c
+++ b/mesalib/src/mesa/vbo/vbo_save_api.c
@@ -724,6 +724,63 @@ do { \
+#define MAT( ATTR, N, face, params ) \
+do { \
+ if (face != GL_BACK) \
+ MAT_ATTR( ATTR, N, params ); /* front */ \
+ if (face != GL_FRONT) \
+ MAT_ATTR( ATTR + 1, N, params ); /* back */ \
+} while (0)
+
+
+/**
+ * Save a glMaterial call found between glBegin/End.
+ * glMaterial calls outside Begin/End are handled in dlist.c.
+ */
+static void GLAPIENTRY
+_save_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_EMISSION:
+ MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params);
+ break;
+ case GL_AMBIENT:
+ MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
+ break;
+ case GL_DIFFUSE:
+ MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
+ break;
+ case GL_SPECULAR:
+ MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params);
+ break;
+ case GL_SHININESS:
+ if (*params < 0 || *params > ctx->Const.MaxShininess) {
+ _mesa_compile_error(ctx, GL_INVALID_VALUE, "glMaterial(shininess)");
+ }
+ else {
+ MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params);
+ }
+ break;
+ case GL_COLOR_INDEXES:
+ MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
+ MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
+ break;
+ default:
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
+ return;
+ }
+}
+
/* Cope with EvalCoord/CallList called within a begin/end object:
* -- Flush current buffer