aboutsummaryrefslogtreecommitdiff
path: root/mesalib
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2014-07-04 19:52:56 +0200
committermarha <marha@users.sourceforge.net>2014-07-04 19:52:56 +0200
commit62ed212e1add98e39c0f7a6e5a8a5726d66f161e (patch)
treea80c4bf566c76665b3449f13fac7de72c66aa80a /mesalib
parent3095a03ec3cb1f05b49362327d10a767299d7635 (diff)
parentfe03d6aef6338e43593f164b09ae993bcd0ecbdd (diff)
downloadvcxsrv-62ed212e1add98e39c0f7a6e5a8a5726d66f161e.tar.gz
vcxsrv-62ed212e1add98e39c0f7a6e5a8a5726d66f161e.tar.bz2
vcxsrv-62ed212e1add98e39c0f7a6e5a8a5726d66f161e.zip
Merge remote-tracking branch 'origin/released'
Diffstat (limited to 'mesalib')
-rw-r--r--mesalib/configure.ac44
-rw-r--r--mesalib/docs/GL3.txt14
-rw-r--r--mesalib/docs/relnotes/10.3.html2
-rw-r--r--mesalib/include/GL/internal/dri_interface.h3
-rw-r--r--mesalib/src/gallium/Automake.inc2
-rw-r--r--mesalib/src/gallium/SConscript2
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_driver_query.c6
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c2
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw.c43
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw.h8
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_dump_state.c3
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_vbuf.c116
-rw-r--r--mesalib/src/glsl/ast_function.cpp50
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp28
-rw-r--r--mesalib/src/glsl/ast_type.cpp22
-rwxr-xr-xmesalib/src/glsl/builtin_functions.cpp3
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp2
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y3
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp42
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h2
-rw-r--r--mesalib/src/glsl/ir.cpp21
-rw-r--r--mesalib/src/glsl/ir_basic_block.cpp7
-rw-r--r--mesalib/src/glsl/ir_clone.cpp28
-rwxr-xr-xmesalib/src/glsl/ir_constant_expression.cpp7
-rw-r--r--mesalib/src/glsl/ir_expression_flattening.cpp4
-rw-r--r--mesalib/src/glsl/ir_function.cpp8
-rw-r--r--mesalib/src/glsl/ir_function_detect_recursion.cpp8
-rw-r--r--mesalib/src/glsl/ir_hv_accept.cpp3
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp30
-rw-r--r--mesalib/src/glsl/ir_reader.cpp29
-rw-r--r--mesalib/src/glsl/ir_rvalue_visitor.cpp3
-rw-r--r--mesalib/src/glsl/ir_validate.cpp8
-rw-r--r--mesalib/src/glsl/link_atomics.cpp4
-rw-r--r--mesalib/src/glsl/link_functions.cpp7
-rw-r--r--mesalib/src/glsl/link_interface_blocks.cpp16
-rw-r--r--mesalib/src/glsl/link_uniform_initializers.cpp4
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp16
-rw-r--r--mesalib/src/glsl/link_varyings.cpp38
-rw-r--r--mesalib/src/glsl/linker.cpp54
-rw-r--r--mesalib/src/glsl/list.h49
-rw-r--r--mesalib/src/glsl/loop_analysis.cpp26
-rw-r--r--mesalib/src/glsl/loop_controls.cpp4
-rw-r--r--mesalib/src/glsl/loop_unroll.cpp6
-rw-r--r--mesalib/src/glsl/lower_discard.cpp4
-rw-r--r--mesalib/src/glsl/lower_if_to_cond_assign.cpp10
-rw-r--r--mesalib/src/glsl/lower_jumps.cpp8
-rw-r--r--mesalib/src/glsl/lower_named_interface_blocks.cpp4
-rw-r--r--mesalib/src/glsl/lower_packed_varyings.cpp7
-rw-r--r--mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp3
-rw-r--r--mesalib/src/glsl/lower_vec_index_to_swizzle.cpp3
-rw-r--r--mesalib/src/glsl/opt_array_splitting.cpp17
-rw-r--r--mesalib/src/glsl/opt_constant_propagation.cpp20
-rw-r--r--mesalib/src/glsl/opt_constant_variable.cpp6
-rw-r--r--mesalib/src/glsl/opt_copy_propagation.cpp17
-rw-r--r--mesalib/src/glsl/opt_copy_propagation_elements.cpp17
-rw-r--r--mesalib/src/glsl/opt_cse.cpp11
-rw-r--r--mesalib/src/glsl/opt_dead_code.cpp6
-rw-r--r--mesalib/src/glsl/opt_dead_code_local.cpp19
-rw-r--r--mesalib/src/glsl/opt_dead_functions.cpp10
-rw-r--r--mesalib/src/glsl/opt_flip_matrices.cpp3
-rw-r--r--mesalib/src/glsl/opt_function_inlining.cpp8
-rw-r--r--mesalib/src/glsl/opt_structure_splitting.cpp13
-rw-r--r--mesalib/src/glsl/opt_vectorize.cpp3
-rw-r--r--mesalib/src/glsl/s_expression.cpp6
-rwxr-xr-xmesalib/src/loader/Makefile.am2
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c3
-rwxr-xr-xmesalib/src/mesa/drivers/dri/common/dri_util.c2
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlconfig.c8
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlconfig.h8
-rw-r--r--mesalib/src/mesa/main/compiler.h14
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/mtypes.h3
-rw-r--r--mesalib/src/mesa/main/shader_query.cpp24
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp31
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_queryobj.c6
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c11
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c11
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp123
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c4
81 files changed, 578 insertions, 650 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 0d4fb0518..4646212be 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -852,6 +852,7 @@ esac
if test "x$enable_dri" = xyes; then
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/dri"
GALLIUM_STATE_TRACKERS_DIRS="dri $GALLIUM_STATE_TRACKERS_DIRS"
+ enable_gallium_loader=yes
fi
if test "x$enable_gallium_osmesa" = xyes; then
@@ -1130,6 +1131,7 @@ if test "x$enable_dri" = xyes; then
EXPAT_LIBS=-lexpat
fi
+ DRICOMMON_NEED_LIBDRM=no
# If we are building any DRI driver other than swrast.
if test -n "$with_dri_drivers"; then
if test "x$with_dri_drivers" != xswrast; then
@@ -1138,8 +1140,14 @@ if test "x$enable_dri" = xyes; then
AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED])
fi
DRICOMMON_NEED_LIBDRM=yes
- else
- DRICOMMON_NEED_LIBDRM=no
+ fi
+ fi
+
+ # If we're building any gallium DRI driver other than swrast
+ if test -n "$with_gallium_drivers" -a "x$DRICOMMON_NEED_LIBDRM" = xno; then
+ if test "x$with_gallium_drivers" != xswrast; then
+ # ... build a libdrm aware dricommon
+ DRICOMMON_NEED_LIBDRM=yes
fi
fi
@@ -1911,23 +1919,21 @@ if test -n "$with_gallium_drivers"; then
HAVE_GALLIUM_SVGA=yes
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga softpipe"
gallium_require_drm_loader
- gallium_check_st "svga/drm" "dri-vmwgfx" "xa/vmwgfx"
+ gallium_check_st "svga/drm" "dri/vmwgfx" "xa/vmwgfx"
;;
xi915)
HAVE_GALLIUM_I915=yes
PKG_CHECK_MODULES([INTEL], [libdrm_intel >= $LIBDRM_INTEL_REQUIRED])
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
- gallium_check_st "i915/drm" "dri-i915" "xa/i915"
- DRICOMMON_NEED_LIBDRM=yes
+ gallium_check_st "i915/drm" "dri/i915" "xa/i915"
;;
xilo)
HAVE_GALLIUM_ILO=yes
PKG_CHECK_MODULES([INTEL], [libdrm_intel >= $LIBDRM_INTEL_REQUIRED])
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS ilo"
- gallium_check_st "intel/drm" "dri-ilo" "xa/ilo"
- DRICOMMON_NEED_LIBDRM=yes
+ gallium_check_st "intel/drm" "dri/ilo" "xa/ilo"
;;
xr300)
HAVE_GALLIUM_R300=yes
@@ -1935,8 +1941,7 @@ if test -n "$with_gallium_drivers"; then
gallium_require_drm_loader
gallium_require_llvm "Gallium R300"
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
- gallium_check_st "radeon/drm" "r300/dri" "xa/r300" "" ""
- DRICOMMON_NEED_LIBDRM=yes
+ gallium_check_st "radeon/drm" "dri/r300" "xa/r300" "" ""
;;
xr600)
HAVE_GALLIUM_R600=yes
@@ -1953,8 +1958,7 @@ if test -n "$with_gallium_drivers"; then
if test "x$enable_opencl" = xyes; then
LLVM_COMPONENTS="${LLVM_COMPONENTS} bitreader asmparser"
fi
- gallium_check_st "radeon/drm" "r600/dri" "xa/r600" "xvmc/r600" "vdpau/r600" "omx/r600"
- DRICOMMON_NEED_LIBDRM=yes
+ gallium_check_st "radeon/drm" "dri/r600" "xa/r600" "xvmc/r600" "vdpau/r600" "omx/r600"
;;
xradeonsi)
HAVE_GALLIUM_RADEONSI=yes
@@ -1963,24 +1967,21 @@ if test -n "$with_gallium_drivers"; then
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi"
radeon_llvm_check "radeonsi"
require_egl_drm "radeonsi"
- gallium_check_st "radeon/drm" "radeonsi/dri" "xa/radeonsi" "" "vdpau/radeonsi" "omx/radeonsi"
- DRICOMMON_NEED_LIBDRM=yes
+ gallium_check_st "radeon/drm" "dri/radeonsi" "xa/radeonsi" "" "vdpau/radeonsi" "omx/radeonsi"
;;
xnouveau)
HAVE_GALLIUM_NOUVEAU=yes
PKG_CHECK_MODULES([NOUVEAU], [libdrm_nouveau >= $LIBDRM_NOUVEAU_REQUIRED])
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau"
- gallium_check_st "nouveau/drm" "dri-nouveau" "xa/nouveau" "xvmc/nouveau" "vdpau/nouveau" "omx/nouveau"
- DRICOMMON_NEED_LIBDRM=yes
+ gallium_check_st "nouveau/drm" "dri/nouveau" "xa/nouveau" "xvmc/nouveau" "vdpau/nouveau" "omx/nouveau"
;;
xfreedreno)
HAVE_GALLIUM_FREEDRENO=yes
PKG_CHECK_MODULES([FREEDRENO], [libdrm_freedreno >= $LIBDRM_FREEDRENO_REQUIRED])
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS freedreno"
- gallium_check_st "freedreno/drm" "dri-freedreno" "xa/freedreno" "" ""
- DRICOMMON_NEED_LIBDRM=yes
+ gallium_check_st "freedreno/drm" "dri/freedreno" "xa/freedreno" "" ""
;;
xswrast)
HAVE_GALLIUM_SOFTPIPE=yes
@@ -2207,12 +2208,8 @@ AC_CONFIG_FILES([Makefile
src/gallium/state_trackers/xa/Makefile
src/gallium/state_trackers/xvmc/Makefile
src/gallium/targets/Makefile
- src/gallium/targets/dri-freedreno/Makefile
- src/gallium/targets/dri-i915/Makefile
- src/gallium/targets/dri-ilo/Makefile
- src/gallium/targets/dri-nouveau/Makefile
src/gallium/targets/dri-swrast/Makefile
- src/gallium/targets/dri-vmwgfx/Makefile
+ src/gallium/targets/dri/Makefile
src/gallium/targets/egl-static/Makefile
src/gallium/targets/gbm/Makefile
src/gallium/targets/libgl-xlib/Makefile
@@ -2221,9 +2218,6 @@ AC_CONFIG_FILES([Makefile
src/gallium/targets/osmesa/Makefile
src/gallium/targets/osmesa/osmesa.pc
src/gallium/targets/pipe-loader/Makefile
- src/gallium/targets/r300/dri/Makefile
- src/gallium/targets/r600/dri/Makefile
- src/gallium/targets/radeonsi/dri/Makefile
src/gallium/targets/vdpau/Makefile
src/gallium/targets/xa/Makefile
src/gallium/targets/xa/xatracker.pc
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt
index bc418a908..296e14cdf 100644
--- a/mesalib/docs/GL3.txt
+++ b/mesalib/docs/GL3.txt
@@ -104,12 +104,12 @@ GL 4.0:
- Dynamically uniform sampler array indices started (Chris)
- Dynamically uniform UBO array indices started (Chris)
- Implicit signed -> unsigned conversions DONE
- - Fused multiply-add DONE
- - Packing/bitfield/conversion functions DONE
- - Enhanced textureGather DONE
- - Geometry shader instancing DONE
- - Geometry shader multiple streams DONE (i965)
- - Enhanced per-sample shading DONE
+ - Fused multiply-add DONE (i965, nvc0)
+ - Packing/bitfield/conversion functions DONE (i965, nvc0)
+ - Enhanced textureGather DONE (i965, nvc0, radeonsi)
+ - Geometry shader instancing DONE (i965, nvc0)
+ - Geometry shader multiple streams DONE (i965, nvc0)
+ - Enhanced per-sample shading DONE (i965)
- Interpolation functions started (Chris)
- New overload resolution rules DONE
GL_ARB_gpu_shader_fp64 started (Dave)
@@ -161,7 +161,7 @@ GL 4.3:
GL_ARB_copy_image not started
GL_KHR_debug DONE (all drivers)
GL_ARB_explicit_uniform_location DONE (all drivers that support GLSL)
- GL_ARB_fragment_layer_viewport not started
+ GL_ARB_fragment_layer_viewport DONE (nv50, nvc0, r600)
GL_ARB_framebuffer_no_attachments not started
GL_ARB_internalformat_query2 not started
GL_ARB_invalidate_subdata DONE (all drivers)
diff --git a/mesalib/docs/relnotes/10.3.html b/mesalib/docs/relnotes/10.3.html
index 47d2c5fff..2e718fc8a 100644
--- a/mesalib/docs/relnotes/10.3.html
+++ b/mesalib/docs/relnotes/10.3.html
@@ -54,6 +54,8 @@ Note: some of the new features are only available with certain drivers.
<li>GL_ARB_texture_query_lod on radeonsi</li>
<li>GL_ARB_viewport_array on nvc0</li>
<li>GL_ARB_seamless_cubemap_per_texture on i965, llvmpipe, nvc0, r600, radeonsi, softpipe</li>
+<li>GL_ARB_fragment_layer_viewport on nv50, nvc0, llvmpipe, r600</li>
+<li>GL_AMD_vertex_shader_viewport_index on i965/gen7+, r600</li>
</ul>
diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h
index 6f5c85676..ad000bdfb 100644
--- a/mesalib/include/GL/internal/dri_interface.h
+++ b/mesalib/include/GL/internal/dri_interface.h
@@ -40,7 +40,6 @@
#ifndef DRI_INTERFACE_H
#define DRI_INTERFACE_H
-#include <stdbool.h>
/* For archs with no drm.h */
#if defined(__APPLE__) || defined(__CYGWIN__) || defined(__GNU__) || defined(_MSC_VER)
#ifndef __NOT_HAVE_DRM_H
@@ -1299,7 +1298,7 @@ typedef struct __DRI2configQueryExtensionRec __DRI2configQueryExtension;
struct __DRI2configQueryExtensionRec {
__DRIextension base;
- int (*configQueryb)(__DRIscreen *screen, const char *var, bool *val);
+ int (*configQueryb)(__DRIscreen *screen, const char *var, unsigned char *val);
int (*configQueryi)(__DRIscreen *screen, const char *var, int *val);
int (*configQueryf)(__DRIscreen *screen, const char *var, float *val);
};
diff --git a/mesalib/src/gallium/Automake.inc b/mesalib/src/gallium/Automake.inc
index 4600b9c5b..e70a1363e 100644
--- a/mesalib/src/gallium/Automake.inc
+++ b/mesalib/src/gallium/Automake.inc
@@ -61,7 +61,7 @@ GALLIUM_DRI_LINKER_FLAGS = \
if HAVE_LD_VERSION_SCRIPT
GALLIUM_DRI_LINKER_FLAGS += \
- -Wl,--version-script=$(top_srcdir)/src/gallium/targets/dri.sym
+ -Wl,--version-script=$(top_srcdir)/src/gallium/targets/dri/dri.sym
endif
diff --git a/mesalib/src/gallium/SConscript b/mesalib/src/gallium/SConscript
index 598b2f1ec..df71b9aea 100644
--- a/mesalib/src/gallium/SConscript
+++ b/mesalib/src/gallium/SConscript
@@ -108,7 +108,7 @@ if not env['embedded']:
if env['dri']:
SConscript([
'targets/dri-swrast/SConscript',
- 'targets/dri-vmwgfx/SConscript',
+ 'targets/dri/SConscript',
])
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
index 0f52e18cc..b48708c2f 100644
--- a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
+++ b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
@@ -90,7 +90,7 @@ query_new_value(struct hud_graph *gr)
NUM_QUERIES);
pipe->destroy_query(pipe, info->query[info->head]);
info->query[info->head] =
- pipe->create_query(pipe, info->query_type);
+ pipe->create_query(pipe, info->query_type, 0);
}
else {
/* the last query is busy, we need to add a new one we can use
@@ -98,7 +98,7 @@ query_new_value(struct hud_graph *gr)
info->head = (info->head+1) % NUM_QUERIES;
if (!info->query[info->head]) {
info->query[info->head] =
- pipe->create_query(pipe, info->query_type);
+ pipe->create_query(pipe, info->query_type, 0);
}
}
break;
@@ -119,7 +119,7 @@ query_new_value(struct hud_graph *gr)
else {
/* initialize */
info->last_time = now;
- info->query[info->head] = pipe->create_query(pipe, info->query_type);
+ info->query[info->head] = pipe->create_query(pipe, info->query_type, 0);
pipe->begin_query(pipe, info->query[info->head]);
}
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index 7b058fe22..db0d1b894 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -325,7 +325,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
}
if (pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) &&
- pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) {
+ pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) {
ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.c b/mesalib/src/gallium/auxiliary/util/u_draw.c
index 83d9284b8..b9f8fcd3c 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw.c
+++ b/mesalib/src/gallium/auxiliary/util/u_draw.c
@@ -27,6 +27,7 @@
#include "util/u_debug.h"
+#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_draw.h"
@@ -123,3 +124,45 @@ util_draw_max_index(
return max_index + 1;
}
+
+
+/* This extracts the draw arguments from the info_in->indirect resource,
+ * puts them into a new instance of pipe_draw_info, and calls draw_vbo on it.
+ */
+void
+util_draw_indirect(struct pipe_context *pipe,
+ const struct pipe_draw_info *info_in)
+{
+ struct pipe_draw_info info;
+ struct pipe_transfer *transfer;
+ uint32_t *params;
+ const unsigned num_params = info_in->indexed ? 5 : 4;
+
+ assert(info_in->indirect);
+ assert(!info_in->count_from_stream_output);
+
+ memcpy(&info, info_in, sizeof(info));
+
+ params = (uint32_t *)
+ pipe_buffer_map_range(pipe,
+ info_in->indirect,
+ info_in->indirect_offset,
+ num_params * sizeof(uint32_t),
+ PIPE_TRANSFER_READ,
+ &transfer);
+ if (!transfer) {
+ debug_printf("%s: failed to map indirect buffer\n", __FUNCTION__);
+ return;
+ }
+
+ info.count = params[0];
+ info.instance_count = params[1];
+ info.start = params[2];
+ info.index_bias = info_in->indexed ? params[3] : 0;
+ info.start_instance = info_in->indexed ? params[4] : params[3];
+ info.indirect = NULL;
+
+ pipe_buffer_unmap(pipe, transfer);
+
+ pipe->draw_vbo(pipe, &info);
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.h b/mesalib/src/gallium/auxiliary/util/u_draw.h
index 5a7ead27e..9fc3e9924 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw.h
+++ b/mesalib/src/gallium/auxiliary/util/u_draw.h
@@ -142,6 +142,14 @@ util_draw_range_elements(struct pipe_context *pipe,
}
+/* This converts an indirect draw into a direct draw by mapping the indirect
+ * buffer, extracting its arguments, and calling pipe->draw_vbo.
+ */
+void
+util_draw_indirect(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
+
+
unsigned
util_draw_max_index(
const struct pipe_vertex_buffer *vertex_buffers,
diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c
index 12f1d2d6e..e6614d5d2 100644
--- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c
+++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c
@@ -759,6 +759,9 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
util_dump_member(stream, ptr, state, count_from_stream_output);
+ util_dump_member(stream, ptr, state, indirect);
+ util_dump_member(stream, uint, state, indirect_offset);
+
util_dump_struct_end(stream);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf.c b/mesalib/src/gallium/auxiliary/util/u_vbuf.c
index 0c9c349e0..c475ee1b3 100644
--- a/mesalib/src/gallium/auxiliary/util/u_vbuf.c
+++ b/mesalib/src/gallium/auxiliary/util/u_vbuf.c
@@ -1013,22 +1013,23 @@ static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr)
static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
struct pipe_index_buffer *ib,
- const struct pipe_draw_info *info,
+ boolean primitive_restart,
+ unsigned restart_index,
+ unsigned start, unsigned count,
int *out_min_index,
int *out_max_index)
{
struct pipe_transfer *transfer = NULL;
const void *indices;
unsigned i;
- unsigned restart_index = info->restart_index;
if (ib->user_buffer) {
indices = (uint8_t*)ib->user_buffer +
- ib->offset + info->start * ib->index_size;
+ ib->offset + start * ib->index_size;
} else {
indices = pipe_buffer_map_range(pipe, ib->buffer,
- ib->offset + info->start * ib->index_size,
- info->count * ib->index_size,
+ ib->offset + start * ib->index_size,
+ count * ib->index_size,
PIPE_TRANSFER_READ, &transfer);
}
@@ -1037,8 +1038,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const unsigned *ui_indices = (const unsigned*)indices;
unsigned max_ui = 0;
unsigned min_ui = ~0U;
- if (info->primitive_restart) {
- for (i = 0; i < info->count; i++) {
+ if (primitive_restart) {
+ for (i = 0; i < count; i++) {
if (ui_indices[i] != restart_index) {
if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
@@ -1046,7 +1047,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
}
}
else {
- for (i = 0; i < info->count; i++) {
+ for (i = 0; i < count; i++) {
if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
}
@@ -1059,8 +1060,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const unsigned short *us_indices = (const unsigned short*)indices;
unsigned max_us = 0;
unsigned min_us = ~0U;
- if (info->primitive_restart) {
- for (i = 0; i < info->count; i++) {
+ if (primitive_restart) {
+ for (i = 0; i < count; i++) {
if (us_indices[i] != restart_index) {
if (us_indices[i] > max_us) max_us = us_indices[i];
if (us_indices[i] < min_us) min_us = us_indices[i];
@@ -1068,7 +1069,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
}
}
else {
- for (i = 0; i < info->count; i++) {
+ for (i = 0; i < count; i++) {
if (us_indices[i] > max_us) max_us = us_indices[i];
if (us_indices[i] < min_us) min_us = us_indices[i];
}
@@ -1081,8 +1082,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const unsigned char *ub_indices = (const unsigned char*)indices;
unsigned max_ub = 0;
unsigned min_ub = ~0U;
- if (info->primitive_restart) {
- for (i = 0; i < info->count; i++) {
+ if (primitive_restart) {
+ for (i = 0; i < count; i++) {
if (ub_indices[i] != restart_index) {
if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
@@ -1090,7 +1091,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
}
}
else {
- for (i = 0; i < info->count; i++) {
+ for (i = 0; i < count; i++) {
if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
}
@@ -1132,6 +1133,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
uint32_t used_vb_mask = mgr->ve->used_vb_mask;
uint32_t user_vb_mask = mgr->user_vb_mask & used_vb_mask;
uint32_t incompatible_vb_mask = mgr->incompatible_vb_mask & used_vb_mask;
+ struct pipe_draw_info new_info;
/* Normal draw. No fallback and no user buffers. */
if (!incompatible_vb_mask &&
@@ -1147,33 +1149,62 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
return;
}
- if (info->indexed) {
+ new_info = *info;
+
+ /* Fallback. We need to know all the parameters. */
+ if (new_info.indirect) {
+ struct pipe_transfer *transfer = NULL;
+ int *data;
+
+ if (new_info.indexed) {
+ data = pipe_buffer_map_range(pipe, new_info.indirect,
+ new_info.indirect_offset, 20,
+ PIPE_TRANSFER_READ, &transfer);
+ new_info.index_bias = data[3];
+ new_info.start_instance = data[4];
+ }
+ else {
+ data = pipe_buffer_map_range(pipe, new_info.indirect,
+ new_info.indirect_offset, 16,
+ PIPE_TRANSFER_READ, &transfer);
+ new_info.start_instance = data[3];
+ }
+
+ new_info.count = data[0];
+ new_info.instance_count = data[1];
+ new_info.start = data[2];
+ pipe_buffer_unmap(pipe, transfer);
+ new_info.indirect = NULL;
+ }
+
+ if (new_info.indexed) {
/* See if anything needs to be done for per-vertex attribs. */
if (u_vbuf_need_minmax_index(mgr)) {
int max_index;
- if (info->max_index != ~0) {
- min_index = info->min_index;
- max_index = info->max_index;
+ if (new_info.max_index != ~0) {
+ min_index = new_info.min_index;
+ max_index = new_info.max_index;
} else {
- u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info,
- &min_index, &max_index);
+ u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer,
+ new_info.primitive_restart,
+ new_info.restart_index, new_info.start,
+ new_info.count, &min_index, &max_index);
}
assert(min_index <= max_index);
- start_vertex = min_index + info->index_bias;
+ start_vertex = min_index + new_info.index_bias;
num_vertices = max_index + 1 - min_index;
/* Primitive restart doesn't work when unrolling indices.
* We would have to break this drawing operation into several ones. */
/* Use some heuristic to see if unrolling indices improves
* performance. */
- if (!info->primitive_restart &&
- num_vertices > info->count*2 &&
- num_vertices-info->count > 32 &&
+ if (!new_info.primitive_restart &&
+ num_vertices > new_info.count*2 &&
+ num_vertices - new_info.count > 32 &&
!u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
- /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/
unroll_indices = TRUE;
user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
mgr->ve->noninstance_vb_mask_any);
@@ -1185,8 +1216,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
min_index = 0;
}
} else {
- start_vertex = info->start;
- num_vertices = info->count;
+ start_vertex = new_info.start;
+ num_vertices = new_info.count;
min_index = 0;
}
@@ -1195,13 +1226,21 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
incompatible_vb_mask ||
mgr->ve->incompatible_elem_mask) {
if (!u_vbuf_translate_begin(mgr, start_vertex, num_vertices,
- info->start_instance, info->instance_count,
- info->start, info->count, min_index,
- unroll_indices)) {
+ new_info.start_instance,
+ new_info.instance_count, new_info.start,
+ new_info.count, min_index, unroll_indices)) {
debug_warn_once("u_vbuf_translate_begin() failed");
return;
}
+ if (unroll_indices) {
+ new_info.indexed = FALSE;
+ new_info.index_bias = 0;
+ new_info.min_index = 0;
+ new_info.max_index = new_info.count - 1;
+ new_info.start = 0;
+ }
+
user_vb_mask &= ~(incompatible_vb_mask |
mgr->ve->incompatible_vb_mask_all);
}
@@ -1209,8 +1248,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
/* Upload user buffers. */
if (user_vb_mask) {
if (u_vbuf_upload_buffers(mgr, start_vertex, num_vertices,
- info->start_instance,
- info->instance_count) != PIPE_OK) {
+ new_info.start_instance,
+ new_info.instance_count) != PIPE_OK) {
debug_warn_once("u_vbuf_upload_buffers() failed");
return;
}
@@ -1242,18 +1281,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
u_upload_unmap(mgr->uploader);
u_vbuf_set_driver_vertex_buffers(mgr);
- if (unlikely(unroll_indices)) {
- struct pipe_draw_info new_info = *info;
- new_info.indexed = FALSE;
- new_info.index_bias = 0;
- new_info.min_index = 0;
- new_info.max_index = info->count - 1;
- new_info.start = 0;
-
- pipe->draw_vbo(pipe, &new_info);
- } else {
- pipe->draw_vbo(pipe, info);
- }
+ pipe->draw_vbo(pipe, &new_info);
if (mgr->using_translate) {
u_vbuf_translate_end(mgr);
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index 8e91a1e67..cdb34cc69 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -41,8 +41,7 @@ process_parameters(exec_list *instructions, exec_list *actual_parameters,
{
unsigned count = 0;
- foreach_list (n, parameters) {
- ast_node *const ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, parameters) {
ir_rvalue *result = ast->hir(instructions, state);
ir_constant *const constant = result->constant_expression_value();
@@ -82,9 +81,7 @@ prototype_string(const glsl_type *return_type, const char *name,
ralloc_asprintf_append(&str, "%s(", name);
const char *comma = "";
- foreach_list(node, parameters) {
- const ir_variable *const param = (ir_variable *) node;
-
+ foreach_in_list(const ir_variable, param, parameters) {
ralloc_asprintf_append(&str, "%s%s", comma, param->type->name);
comma = ", ";
}
@@ -158,12 +155,11 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
exec_node *actual_ir_node = actual_ir_parameters.head;
exec_node *actual_ast_node = actual_ast_parameters.head;
- foreach_list(formal_node, &sig->parameters) {
+ foreach_in_list(const ir_variable, formal, &sig->parameters) {
/* The lists must be the same length. */
assert(!actual_ir_node->is_tail_sentinel());
assert(!actual_ast_node->is_tail_sentinel());
- const ir_variable *const formal = (ir_variable *) formal_node;
const ir_rvalue *const actual = (ir_rvalue *) actual_ir_node;
const ast_expression *const actual_ast =
exec_node_data(ast_expression, actual_ast_node, link);
@@ -478,9 +474,7 @@ print_function_prototypes(_mesa_glsl_parse_state *state, YYLTYPE *loc,
if (f == NULL)
return;
- foreach_list (node, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) node;
-
+ foreach_in_list(ir_function_signature, sig, &f->signatures) {
if (sig->is_builtin() && !sig->is_builtin_available(state))
continue;
@@ -690,8 +684,7 @@ process_vec_mat_constructor(exec_list *instructions,
bool all_parameters_are_constant = true;
/* Type cast each parameter and, if possible, fold constants. */
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *ir = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
ir_rvalue *result = ir;
/* Apply implicit conversions (not the scalar constructor rules!). See
@@ -749,8 +742,7 @@ process_vec_mat_constructor(exec_list *instructions,
instructions->push_tail(var);
int i = 0;
- foreach_list(node, &actual_parameters) {
- ir_rvalue *rhs = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
new(ctx) ir_constant(i));
@@ -819,8 +811,7 @@ process_array_constructor(exec_list *instructions,
bool all_parameters_are_constant = true;
/* Type cast each parameter and, if possible, fold constants. */
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *ir = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
ir_rvalue *result = ir;
/* Apply implicit conversions (not the scalar constructor rules!). See
@@ -870,8 +861,7 @@ process_array_constructor(exec_list *instructions,
instructions->push_tail(var);
int i = 0;
- foreach_list(node, &actual_parameters) {
- ir_rvalue *rhs = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
new(ctx) ir_constant(i));
@@ -892,8 +882,8 @@ static ir_constant *
constant_record_constructor(const glsl_type *constructor_type,
exec_list *parameters, void *mem_ctx)
{
- foreach_list(node, parameters) {
- ir_constant *constant = ((ir_instruction *) node)->as_constant();
+ foreach_in_list(ir_instruction, node, parameters) {
+ ir_constant *constant = node->as_constant();
if (constant == NULL)
return NULL;
node->replace_with(constant);
@@ -967,8 +957,7 @@ emit_inline_vector_constructor(const glsl_type *type,
memset(&data, 0, sizeof(data));
- foreach_list(node, parameters) {
- ir_rvalue *param = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, param, parameters) {
unsigned rhs_components = param->type->components();
/* Do not try to assign more components to the vector than it has!
@@ -1025,8 +1014,7 @@ emit_inline_vector_constructor(const glsl_type *type,
}
base_component = 0;
- foreach_list(node, parameters) {
- ir_rvalue *param = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, param, parameters) {
unsigned rhs_components = param->type->components();
/* Do not try to assign more components to the vector than it has!
@@ -1312,8 +1300,7 @@ emit_inline_matrix_constructor(const glsl_type *type,
unsigned col_idx = 0;
unsigned row_idx = 0;
- foreach_list (node, parameters) {
- ir_rvalue *const rhs = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, rhs, parameters) {
const unsigned components_remaining_this_column = rows - row_idx;
unsigned rhs_components = rhs->type->components();
unsigned rhs_base = 0;
@@ -1558,8 +1545,7 @@ ast_function_expression::hir(exec_list *instructions,
unsigned nonmatrix_parameters = 0;
exec_list actual_parameters;
- foreach_list (n, &this->expressions) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, &this->expressions) {
ir_rvalue *result = ast->hir(instructions, state);
/* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
@@ -1639,9 +1625,7 @@ ast_function_expression::hir(exec_list *instructions,
* need to break them up into a series of column vectors.
*/
if (constructor_type->base_type != GLSL_TYPE_FLOAT) {
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *matrix = (ir_rvalue *) n;
-
+ foreach_in_list_safe(ir_rvalue, matrix, &actual_parameters) {
if (!matrix->type->is_matrix())
continue;
@@ -1665,9 +1649,7 @@ ast_function_expression::hir(exec_list *instructions,
bool all_parameters_are_constant = true;
/* Type cast each parameter and, if possible, fold constants.*/
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *ir = (ir_rvalue *) n;
-
+ foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
const glsl_type *desired_type =
glsl_type::get_instance(constructor_type->base_type,
ir->type->vector_elements,
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 042ef243b..885bee547 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -112,8 +112,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
* applications depend on this behavior, and it matches what nearly all
* other drivers do.
*/
- foreach_list_safe(node, instructions) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list_safe(ir_instruction, node, instructions) {
+ ir_variable *const var = node->as_variable();
if (var == NULL)
continue;
@@ -4210,10 +4210,8 @@ ast_function_definition::hir(exec_list *instructions,
* Add these to the symbol table.
*/
state->symbols->push_scope();
- foreach_list(n, &signature->parameters) {
- ir_variable *const var = ((ir_instruction *) n)->as_variable();
-
- assert(var != NULL);
+ foreach_in_list(ir_variable, var, &signature->parameters) {
+ assert(var->as_variable() != NULL);
/* The only way a parameter would "exist" is if two parameters have
* the same name.
@@ -5009,7 +5007,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
* 'declarations' list in each of the elements.
*/
foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
- foreach_list_const (decl_ptr, & decl_list->declarations) {
+ foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) {
decl_count++;
}
}
@@ -5621,8 +5619,8 @@ ast_interface_block::hir(exec_list *instructions,
* thinking there are conflicting definitions of gl_PerVertex in the
* shader.
*/
- foreach_list_safe(node, instructions) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list_safe(ir_instruction, node, instructions) {
+ ir_variable *const var = node->as_variable();
if (var != NULL &&
var->get_interface_type() == earlier_per_vertex &&
var->data.mode == var_mode) {
@@ -5678,8 +5676,8 @@ ast_gs_input_layout::hir(exec_list *instructions,
/* If any shader inputs occurred before this declaration and did not
* specify an array size, their size is determined now.
*/
- foreach_list (node, instructions) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, instructions) {
+ ir_variable *var = node->as_variable();
if (var == NULL || var->data.mode != ir_var_shader_in)
continue;
@@ -5796,8 +5794,8 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
YYLTYPE loc;
memset(&loc, 0, sizeof(loc));
- foreach_list(node, instructions) {
- ir_variable *var = ((ir_instruction *)node)->as_variable();
+ foreach_in_list(ir_instruction, node, instructions) {
+ ir_variable *var = node->as_variable();
if (!var || !var->data.assigned)
continue;
@@ -5886,8 +5884,8 @@ remove_per_vertex_blocks(exec_list *instructions,
/* Remove any ir_variable declarations that refer to the interface block
* we're removing.
*/
- foreach_list_safe(node, instructions) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list_safe(ir_instruction, node, instructions) {
+ ir_variable *const var = node->as_variable();
if (var != NULL && var->get_interface_type() == per_vertex &&
var->data.mode == mode) {
state->symbols->disable_variable(var->name);
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp
index 017f23d0e..de4c1a410 100644
--- a/mesalib/src/glsl/ast_type.cpp
+++ b/mesalib/src/glsl/ast_type.cpp
@@ -122,18 +122,28 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
ubo_binding_mask.flags.q.explicit_binding = 1;
ubo_binding_mask.flags.q.explicit_offset = 1;
+ ast_type_qualifier stream_layout_mask;
+ stream_layout_mask.flags.i = 0;
+ stream_layout_mask.flags.q.stream = 1;
+
/* Uniform block layout qualifiers get to overwrite each
* other (rightmost having priority), while all other
* qualifiers currently don't allow duplicates.
- *
- * Geometry shaders can have several layout qualifiers
+ */
+ ast_type_qualifier allowed_duplicates_mask;
+ allowed_duplicates_mask.flags.i =
+ ubo_mat_mask.flags.i |
+ ubo_layout_mask.flags.i |
+ ubo_binding_mask.flags.i;
+
+ /* Geometry shaders can have several layout qualifiers
* assigning different stream values.
*/
+ if (state->stage == MESA_SHADER_GEOMETRY)
+ allowed_duplicates_mask.flags.i |=
+ stream_layout_mask.flags.i;
- if ((state->stage != MESA_SHADER_GEOMETRY) &&
- (this->flags.i & q.flags.i & ~(ubo_mat_mask.flags.i |
- ubo_layout_mask.flags.i |
- ubo_binding_mask.flags.i)) != 0) {
+ if ((this->flags.i & q.flags.i & ~allowed_duplicates_mask.flags.i) != 0) {
_mesa_glsl_error(loc, state,
"duplicate layout qualifiers used");
return false;
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
index ee92384d6..a987ab2c2 100755
--- a/mesalib/src/glsl/builtin_functions.cpp
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -2575,8 +2575,7 @@ builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
{
exec_list actual_params;
- foreach_list(node, &params) {
- ir_variable *var = (ir_variable *) node;
+ foreach_in_list(ir_variable, var, &params) {
actual_params.push_tail(var_ref(var));
}
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index 9f9571619..34973023f 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -815,6 +815,8 @@ builtin_variable_generator::generate_vs_special_vars()
add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, "gl_InstanceID");
if (state->AMD_vertex_shader_layer_enable)
add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer");
+ if (state->AMD_vertex_shader_viewport_index_enable)
+ add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex");
if (compatibility) {
add_input(VERT_ATTRIB_POS, vec4_t, "gl_Vertex");
add_input(VERT_ATTRIB_NORMAL, vec3_t, "gl_Normal");
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index d8c395778..ccf810559 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -2133,6 +2133,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
if (extensions->AMD_vertex_shader_layer)
add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1);
+ if (extensions->AMD_vertex_shader_viewport_index)
+ add_builtin_define(parser, "GL_AMD_vertex_shader_viewport_index", 1);
+
if (extensions->ARB_shading_language_420pack)
add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 11a9a4320..b327c2b43 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -552,6 +552,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(AMD_shader_stencil_export, true, false, ARB_shader_stencil_export),
EXT(AMD_shader_trinary_minmax, true, false, dummy_true),
EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer),
+ EXT(AMD_vertex_shader_viewport_index, true, false, AMD_vertex_shader_viewport_index),
EXT(EXT_separate_shader_objects, false, true, dummy_true),
EXT(EXT_shader_integer_mix, true, true, EXT_shader_integer_mix),
EXT(EXT_texture_array, true, false, EXT_texture_array),
@@ -844,8 +845,7 @@ ast_compound_statement::print(void) const
{
printf("{\n");
- foreach_list_const(n, &this->statements) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, &this->statements) {
ast->print();
}
@@ -924,11 +924,10 @@ ast_expression::print(void) const
subexpressions[0]->print();
printf("( ");
- foreach_list_const (n, &this->expressions) {
- if (n != this->expressions.get_head())
+ foreach_list_typed (ast_node, ast, link, &this->expressions) {
+ if (&ast->link != this->expressions.get_head())
printf(", ");
- ast_node *ast = exec_node_data(ast_node, n, link);
ast->print();
}
@@ -960,11 +959,10 @@ ast_expression::print(void) const
case ast_sequence: {
printf("( ");
- foreach_list_const(n, & this->expressions) {
- if (n != this->expressions.get_head())
+ foreach_list_typed (ast_node, ast, link, & this->expressions) {
+ if (&ast->link != this->expressions.get_head())
printf(", ");
- ast_node *ast = exec_node_data(ast_node, n, link);
ast->print();
}
printf(") ");
@@ -973,11 +971,10 @@ ast_expression::print(void) const
case ast_aggregate: {
printf("{ ");
- foreach_list_const(n, & this->expressions) {
- if (n != this->expressions.get_head())
+ foreach_list_typed (ast_node, ast, link, & this->expressions) {
+ if (&ast->link != this->expressions.get_head())
printf(", ");
- ast_node *ast = exec_node_data(ast_node, n, link);
ast->print();
}
printf("} ");
@@ -1027,8 +1024,7 @@ ast_function::print(void) const
return_type->print();
printf(" %s (", identifier);
- foreach_list_const(n, & this->parameters) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, & this->parameters) {
ast->print();
}
@@ -1105,11 +1101,10 @@ ast_declarator_list::print(void) const
else
printf("precise ");
- foreach_list_const (ptr, & this->declarations) {
- if (ptr != this->declarations.get_head())
+ foreach_list_typed (ast_node, ast, link, & this->declarations) {
+ if (&ast->link != this->declarations.get_head())
printf(", ");
- ast_node *ast = exec_node_data(ast_node, ptr, link);
ast->print();
}
@@ -1241,8 +1236,7 @@ ast_case_label::ast_case_label(ast_expression *test_value)
void ast_case_label_list::print(void) const
{
- foreach_list_const(n, & this->labels) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, & this->labels) {
ast->print();
}
printf("\n");
@@ -1257,8 +1251,7 @@ ast_case_label_list::ast_case_label_list(void)
void ast_case_statement::print(void) const
{
labels->print();
- foreach_list_const(n, & this->stmts) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, & this->stmts) {
ast->print();
printf("\n");
}
@@ -1273,8 +1266,7 @@ ast_case_statement::ast_case_statement(ast_case_label_list *labels)
void ast_case_statement_list::print(void) const
{
- foreach_list_const(n, & this->cases) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, & this->cases) {
ast->print();
}
}
@@ -1344,8 +1336,7 @@ void
ast_struct_specifier::print(void) const
{
printf("struct %s { ", name);
- foreach_list_const(n, &this->declarations) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, &this->declarations) {
ast->print();
}
printf("} ");
@@ -1456,8 +1447,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
}
if (dump_ast) {
- foreach_list_const(n, &state->translation_unit) {
- ast_node *ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, &state->translation_unit) {
ast->print();
}
printf("\n\n");
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index fd1391c2a..0ea3ce34a 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -465,6 +465,8 @@ struct _mesa_glsl_parse_state {
bool AMD_shader_trinary_minmax_warn;
bool AMD_vertex_shader_layer_enable;
bool AMD_vertex_shader_layer_warn;
+ bool AMD_vertex_shader_viewport_index_enable;
+ bool AMD_vertex_shader_viewport_index_warn;
bool EXT_separate_shader_objects_enable;
bool EXT_separate_shader_objects_warn;
bool EXT_shader_integer_mix_enable;
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 67dbac1eb..4b14668ea 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -699,8 +699,7 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
if (type->is_array()) {
this->array_elements = ralloc_array(this, ir_constant *, type->length);
unsigned i = 0;
- foreach_list(node, value_list) {
- ir_constant *value = (ir_constant *) node;
+ foreach_in_list(ir_constant, value, value_list) {
assert(value->as_constant() != NULL);
this->array_elements[i++] = value;
@@ -1001,9 +1000,7 @@ ir_constant::copy_offset(ir_constant *src, int offset)
case GLSL_TYPE_STRUCT: {
assert (src->type == this->type);
this->components.make_empty();
- foreach_list(node, &src->components) {
- ir_constant *const orig = (ir_constant *) node;
-
+ foreach_in_list(ir_constant, orig, &src->components) {
this->components.push_tail(orig->clone(this, NULL));
}
break;
@@ -1702,8 +1699,7 @@ ir_function::ir_function(const char *name)
bool
ir_function::has_user_signature()
{
- foreach_list(n, &this->signatures) {
- ir_function_signature *const sig = (ir_function_signature *) n;
+ foreach_in_list(ir_function_signature, sig, &this->signatures) {
if (!sig->is_builtin())
return true;
}
@@ -1724,8 +1720,8 @@ ir_rvalue::error_value(void *mem_ctx)
void
visit_exec_list(exec_list *list, ir_visitor *visitor)
{
- foreach_list_safe(n, list) {
- ((ir_instruction *) n)->accept(visitor);
+ foreach_in_list_safe(ir_instruction, node, list) {
+ node->accept(visitor);
}
}
@@ -1746,8 +1742,7 @@ steal_memory(ir_instruction *ir, void *new_ctx)
*/
if (constant != NULL) {
if (constant->type->is_record()) {
- foreach_list(n, &constant->components) {
- ir_constant *field = (ir_constant *) n;
+ foreach_in_list(ir_constant, field, &constant->components) {
steal_memory(field, ir);
}
} else if (constant->type->is_array()) {
@@ -1764,8 +1759,8 @@ steal_memory(ir_instruction *ir, void *new_ctx)
void
reparent_ir(exec_list *list, void *mem_ctx)
{
- foreach_list(node, list) {
- visit_tree((ir_instruction *) node, steal_memory, mem_ctx);
+ foreach_in_list(ir_instruction, node, list) {
+ visit_tree(node, steal_memory, mem_ctx);
}
}
diff --git a/mesalib/src/glsl/ir_basic_block.cpp b/mesalib/src/glsl/ir_basic_block.cpp
index 74ee4b696..15481aa47 100644
--- a/mesalib/src/glsl/ir_basic_block.cpp
+++ b/mesalib/src/glsl/ir_basic_block.cpp
@@ -56,8 +56,7 @@ void call_for_basic_blocks(exec_list *instructions,
ir_instruction *leader = NULL;
ir_instruction *last = NULL;
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, instructions) {
ir_if *ir_if;
ir_loop *ir_loop;
ir_function *ir_function;
@@ -88,9 +87,7 @@ void call_for_basic_blocks(exec_list *instructions,
* and the body of main(). Perhaps those instructions ought
* to live inside of main().
*/
- foreach_list(func_node, &ir_function->signatures) {
- ir_function_signature *ir_sig = (ir_function_signature *) func_node;
-
+ foreach_in_list(ir_function_signature, ir_sig, &ir_function->signatures) {
call_for_basic_blocks(&ir_sig->body, callback, data);
}
}
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index c00adc564..4b444d468 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -123,13 +123,11 @@ ir_if::clone(void *mem_ctx, struct hash_table *ht) const
{
ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht));
- foreach_list(n, &this->then_instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, &this->then_instructions) {
new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht));
}
- foreach_list(n, &this->else_instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, &this->else_instructions) {
new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht));
}
@@ -141,8 +139,7 @@ ir_loop::clone(void *mem_ctx, struct hash_table *ht) const
{
ir_loop *new_loop = new(mem_ctx) ir_loop();
- foreach_list(n, &this->body_instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, &this->body_instructions) {
new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht));
}
@@ -158,8 +155,7 @@ ir_call::clone(void *mem_ctx, struct hash_table *ht) const
exec_list new_parameters;
- foreach_list(n, &this->actual_parameters) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, &this->actual_parameters) {
new_parameters.push_tail(ir->clone(mem_ctx, ht));
}
@@ -278,10 +274,7 @@ ir_function::clone(void *mem_ctx, struct hash_table *ht) const
{
ir_function *copy = new(mem_ctx) ir_function(this->name);
- foreach_list_const(node, &this->signatures) {
- const ir_function_signature *const sig =
- (const ir_function_signature *const) node;
-
+ foreach_in_list(const ir_function_signature, sig, &this->signatures) {
ir_function_signature *sig_copy = sig->clone(mem_ctx, ht);
copy->add_signature(sig_copy);
@@ -302,9 +295,7 @@ ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const
/* Clone the instruction list.
*/
- foreach_list_const(node, &this->body) {
- const ir_instruction *const inst = (const ir_instruction *) node;
-
+ foreach_in_list(const ir_instruction, inst, &this->body) {
ir_instruction *const inst_copy = inst->clone(mem_ctx, ht);
copy->body.push_tail(inst_copy);
}
@@ -324,9 +315,7 @@ ir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) con
/* Clone the parameter list, but NOT the body.
*/
- foreach_list_const(node, &this->parameters) {
- const ir_variable *const param = (const ir_variable *) node;
-
+ foreach_in_list(const ir_variable, param, &this->parameters) {
assert(const_cast<ir_variable *>(param)->as_variable() != NULL);
ir_variable *const param_copy = param->clone(mem_ctx, ht);
@@ -430,8 +419,7 @@ clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in)
struct hash_table *ht =
hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare);
- foreach_list_const(node, in) {
- const ir_instruction *const original = (ir_instruction *) node;
+ foreach_in_list(const ir_instruction, original, in) {
ir_instruction *copy = original->clone(mem_ctx, ht);
out->push_tail(copy);
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index 73380d243..fa59cc16a 100755
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -1775,8 +1775,7 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s
struct hash_table *variable_context,
ir_constant **result)
{
- foreach_list(n, &body) {
- ir_instruction *inst = (ir_instruction *)n;
+ foreach_in_list(ir_instruction, inst, &body) {
switch(inst->ir_type) {
/* (declare () type symbol) */
@@ -1915,8 +1914,8 @@ ir_function_signature::constant_expression_value(exec_list *actual_parameters, s
*/
const exec_node *parameter_info = origin ? origin->parameters.head : parameters.head;
- foreach_list(n, actual_parameters) {
- ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(variable_context);
+ foreach_in_list(ir_rvalue, n, actual_parameters) {
+ ir_constant *constant = n->constant_expression_value(variable_context);
if (constant == NULL) {
hash_table_dtor(deref_hash);
return NULL;
diff --git a/mesalib/src/glsl/ir_expression_flattening.cpp b/mesalib/src/glsl/ir_expression_flattening.cpp
index 0b1ada519..c13ae811d 100644
--- a/mesalib/src/glsl/ir_expression_flattening.cpp
+++ b/mesalib/src/glsl/ir_expression_flattening.cpp
@@ -57,9 +57,7 @@ do_expression_flattening(exec_list *instructions,
{
ir_expression_flattening_visitor v(predicate);
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
-
+ foreach_in_list(ir_instruction, ir, instructions) {
ir->accept(&v);
}
}
diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp
index deec1dfe8..7d6c2f451 100644
--- a/mesalib/src/glsl/ir_function.cpp
+++ b/mesalib/src/glsl/ir_function.cpp
@@ -306,9 +306,7 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state,
* multiple ways to apply these conversions to the actual arguments of a
* call such that the call can be made to match multiple signatures."
*/
- foreach_list(n, &this->signatures) {
- ir_function_signature *const sig = (ir_function_signature *) n;
-
+ foreach_in_list(ir_function_signature, sig, &this->signatures) {
/* Skip over any built-ins that aren't available in this shader. */
if (sig->is_builtin() && !sig->is_builtin_available(state))
continue;
@@ -380,9 +378,7 @@ ir_function_signature *
ir_function::exact_matching_signature(_mesa_glsl_parse_state *state,
const exec_list *actual_parameters)
{
- foreach_list(n, &this->signatures) {
- ir_function_signature *const sig = (ir_function_signature *) n;
-
+ foreach_in_list(ir_function_signature, sig, &this->signatures) {
/* Skip over any built-ins that aren't available in this shader. */
if (sig->is_builtin() && !sig->is_builtin_available(state))
continue;
diff --git a/mesalib/src/glsl/ir_function_detect_recursion.cpp b/mesalib/src/glsl/ir_function_detect_recursion.cpp
index 5813315b6..b2334d2e4 100644
--- a/mesalib/src/glsl/ir_function_detect_recursion.cpp
+++ b/mesalib/src/glsl/ir_function_detect_recursion.cpp
@@ -229,15 +229,13 @@ public:
static void
destroy_links(exec_list *list, function *f)
{
- foreach_list_safe(node, list) {
- struct call_node *n = (struct call_node *) node;
-
+ foreach_in_list_safe(call_node, node, list) {
/* If this is the right function, remove it. Note that the loop cannot
* terminate now. There can be multiple links to a function if it is
* either called multiple times or calls multiple times.
*/
- if (n->func == f)
- n->remove();
+ if (node->func == f)
+ node->remove();
}
}
diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp
index 3ca7a5887..be5b3eaa0 100644
--- a/mesalib/src/glsl/ir_hv_accept.cpp
+++ b/mesalib/src/glsl/ir_hv_accept.cpp
@@ -49,8 +49,7 @@ visit_list_elements(ir_hierarchical_visitor *v, exec_list *l,
{
ir_instruction *prev_base_ir = v->base_ir;
- foreach_list_safe(n, l) {
- ir_instruction *const ir = (ir_instruction *) n;
+ foreach_in_list_safe(ir_instruction, ir, l) {
if (statement_list)
v->base_ir = ir;
ir_visitor_status s = ir->accept(v);
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index 72ad4223f..bd398052c 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -67,8 +67,7 @@ _mesa_print_ir(FILE *f, exec_list *instructions,
}
fprintf(f, "(\n");
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, instructions) {
ir->fprint(f);
if (ir->ir_type != ir_type_function)
fprintf(f, "\n");
@@ -196,9 +195,7 @@ void ir_print_visitor::visit(ir_function_signature *ir)
fprintf(f, "(parameters\n");
indentation++;
- foreach_list(n, &ir->parameters) {
- ir_variable *const inst = (ir_variable *) n;
-
+ foreach_in_list(ir_variable, inst, &ir->parameters) {
indent();
inst->accept(this);
fprintf(f, "\n");
@@ -213,9 +210,7 @@ void ir_print_visitor::visit(ir_function_signature *ir)
fprintf(f, "(\n");
indentation++;
- foreach_list(n, &ir->body) {
- ir_instruction *const inst = (ir_instruction *) n;
-
+ foreach_in_list(ir_instruction, inst, &ir->body) {
indent();
inst->accept(this);
fprintf(f, "\n");
@@ -232,8 +227,7 @@ void ir_print_visitor::visit(ir_function *ir)
{
fprintf(f, "(function %s\n", ir->name);
indentation++;
- foreach_list(n, &ir->signatures) {
- ir_function_signature *const sig = (ir_function_signature *) n;
+ foreach_in_list(ir_function_signature, sig, &ir->signatures) {
indent();
sig->accept(this);
fprintf(f, "\n");
@@ -457,9 +451,7 @@ ir_print_visitor::visit(ir_call *ir)
if (ir->return_deref)
ir->return_deref->accept(this);
fprintf(f, " (");
- foreach_list(n, &ir->actual_parameters) {
- ir_rvalue *const param = (ir_rvalue *) n;
-
+ foreach_in_list(ir_rvalue, param, &ir->actual_parameters) {
param->accept(this);
}
fprintf(f, "))\n");
@@ -504,9 +496,7 @@ ir_print_visitor::visit(ir_if *ir)
fprintf(f, "(\n");
indentation++;
- foreach_list(n, &ir->then_instructions) {
- ir_instruction *const inst = (ir_instruction *) n;
-
+ foreach_in_list(ir_instruction, inst, &ir->then_instructions) {
indent();
inst->accept(this);
fprintf(f, "\n");
@@ -521,9 +511,7 @@ ir_print_visitor::visit(ir_if *ir)
fprintf(f, "(\n");
indentation++;
- foreach_list(n, &ir->else_instructions) {
- ir_instruction *const inst = (ir_instruction *) n;
-
+ foreach_in_list(ir_instruction, inst, &ir->else_instructions) {
indent();
inst->accept(this);
fprintf(f, "\n");
@@ -543,9 +531,7 @@ ir_print_visitor::visit(ir_loop *ir)
fprintf(f, "(loop (\n");
indentation++;
- foreach_list(n, &ir->body_instructions) {
- ir_instruction *const inst = (ir_instruction *) n;
-
+ foreach_in_list(ir_instruction, inst, &ir->body_instructions) {
indent();
inst->accept(this);
fprintf(f, "\n");
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index a178c82b5..4017bdd73 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -170,9 +170,8 @@ ir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr)
return;
}
- foreach_list(n, &list->subexpressions) {
- s_list *sub = SX_AS_LIST(n);
- if (sub == NULL)
+ foreach_in_list(s_list, sub, &list->subexpressions) {
+ if (!sub->is_list())
continue; // not a (function ...); ignore it.
s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
@@ -317,8 +316,7 @@ ir_reader::read_instructions(exec_list *instructions, s_expression *expr,
return;
}
- foreach_list(n, &list->subexpressions) {
- s_expression *sub = (s_expression *) n;
+ foreach_in_list(s_expression, sub, &list->subexpressions) {
ir_instruction *ir = read_instruction(sub, loop_ctx);
if (ir != NULL) {
/* Global variable declarations should be moved to the top, before
@@ -405,9 +403,8 @@ ir_reader::read_declaration(s_expression *expr)
ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(),
ir_var_auto);
- foreach_list(n, &s_quals->subexpressions) {
- s_symbol *qualifier = SX_AS_SYMBOL(n);
- if (qualifier == NULL) {
+ foreach_in_list(s_symbol, qualifier, &s_quals->subexpressions) {
+ if (!qualifier->is_symbol()) {
ir_read_error(expr, "qualifier list must contain only symbols");
return NULL;
}
@@ -664,11 +661,10 @@ ir_reader::read_call(s_expression *expr)
exec_list parameters;
- foreach_list(n, &params->subexpressions) {
- s_expression *expr = (s_expression *) n;
- ir_rvalue *param = read_rvalue(expr);
+ foreach_in_list(s_expression, e, &params->subexpressions) {
+ ir_rvalue *param = read_rvalue(e);
if (param == NULL) {
- ir_read_error(expr, "when reading parameter to function call");
+ ir_read_error(e, "when reading parameter to function call");
return NULL;
}
parameters.push_tail(param);
@@ -729,7 +725,7 @@ ir_reader::read_expression(s_expression *expr)
}
int num_operands = -3; /* skip "expression" <type> <operation> */
- foreach_list(n, &((s_list *) expr)->subexpressions)
+ foreach_in_list(s_expression, e, &((s_list *) expr)->subexpressions)
++num_operands;
int expected_operands = ir_expression::get_num_operands(op);
@@ -804,8 +800,7 @@ ir_reader::read_constant(s_expression *expr)
if (type->is_array()) {
unsigned elements_supplied = 0;
exec_list elements;
- foreach_list(n, &values->subexpressions) {
- s_expression *elt = (s_expression *) n;
+ foreach_in_list(s_expression, elt, &values->subexpressions) {
ir_constant *ir_elt = read_constant(elt);
if (ir_elt == NULL)
return NULL;
@@ -825,14 +820,12 @@ ir_reader::read_constant(s_expression *expr)
// Read in list of values (at most 16).
unsigned k = 0;
- foreach_list(n, &values->subexpressions) {
+ foreach_in_list(s_expression, expr, &values->subexpressions) {
if (k >= 16) {
ir_read_error(values, "expected at most 16 numbers");
return NULL;
}
- s_expression *expr = (s_expression *) n;
-
if (type->base_type == GLSL_TYPE_FLOAT) {
s_number *value = SX_AS_NUMBER(expr);
if (value == NULL) {
diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp
index 0370170b3..34cdb1c98 100644
--- a/mesalib/src/glsl/ir_rvalue_visitor.cpp
+++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp
@@ -123,8 +123,7 @@ ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir)
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_call *ir)
{
- foreach_list_safe(n, &ir->actual_parameters) {
- ir_rvalue *param = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) {
ir_rvalue *new_param = param;
handle_rvalue(&new_param);
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 17a74ea55..271dbe096 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -172,9 +172,7 @@ ir_validate::visit_enter(ir_function *ir)
/* Verify that all of the things stored in the list of signatures are,
* in fact, function signatures.
*/
- foreach_list(node, &ir->signatures) {
- ir_instruction *sig = (ir_instruction *) node;
-
+ foreach_in_list(ir_instruction, sig, &ir->signatures) {
if (sig->ir_type != ir_type_function_signature) {
printf("Non-signature in signature list of function `%s'\n",
ir->name);
@@ -816,9 +814,7 @@ validate_ir_tree(exec_list *instructions)
v.run(instructions);
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
-
+ foreach_in_list(ir_instruction, ir, instructions) {
visit_tree(ir, check_node_type, NULL);
}
#endif
diff --git a/mesalib/src/glsl/link_atomics.cpp b/mesalib/src/glsl/link_atomics.cpp
index fbe4e7364..75699fd93 100644
--- a/mesalib/src/glsl/link_atomics.cpp
+++ b/mesalib/src/glsl/link_atomics.cpp
@@ -110,8 +110,8 @@ namespace {
if (sh == NULL)
continue;
- foreach_list(node, sh->ir) {
- ir_variable *var = ((ir_instruction *)node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
if (var && var->type->contains_atomic()) {
unsigned id = 0;
diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp
index 56f3f207e..2ce9609b5 100644
--- a/mesalib/src/glsl/link_functions.cpp
+++ b/mesalib/src/glsl/link_functions.cpp
@@ -145,8 +145,7 @@ public:
struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash,
hash_table_pointer_compare);
exec_list formal_parameters;
- foreach_list_const(node, &sig->parameters) {
- const ir_instruction *const original = (ir_instruction *) node;
+ foreach_in_list(const ir_instruction, original, &sig->parameters) {
assert(const_cast<ir_instruction *>(original)->as_variable());
ir_instruction *copy = original->clone(linked, ht);
@@ -156,9 +155,7 @@ public:
linked_sig->replace_parameters(&formal_parameters);
if (sig->is_defined) {
- foreach_list_const(node, &sig->body) {
- const ir_instruction *const original = (ir_instruction *) node;
-
+ foreach_in_list(const ir_instruction, original, &sig->body) {
ir_instruction *copy = original->clone(linked, ht);
linked_sig->body.push_tail(copy);
}
diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp
index 52552cc68..0ce502d4f 100644
--- a/mesalib/src/glsl/link_interface_blocks.cpp
+++ b/mesalib/src/glsl/link_interface_blocks.cpp
@@ -259,8 +259,8 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog,
if (shader_list[i] == NULL)
continue;
- foreach_list(node, shader_list[i]->ir) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
+ ir_variable *var = node->as_variable();
if (!var)
continue;
@@ -316,8 +316,8 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog,
const bool extra_array_level = consumer->Stage == MESA_SHADER_GEOMETRY;
/* Add input interfaces from the consumer to the symbol table. */
- foreach_list(node, consumer->ir) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, consumer->ir) {
+ ir_variable *var = node->as_variable();
if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
continue;
@@ -325,8 +325,8 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog,
}
/* Verify that the producer's output interfaces match. */
- foreach_list(node, producer->ir) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, producer->ir) {
+ ir_variable *var = node->as_variable();
if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
continue;
@@ -359,8 +359,8 @@ validate_interstage_uniform_blocks(struct gl_shader_program *prog,
continue;
const gl_shader *stage = stages[i];
- foreach_list(node, stage->ir) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, stage->ir) {
+ ir_variable *var = node->as_variable();
if (!var || !var->get_interface_type() || var->data.mode != ir_var_uniform)
continue;
diff --git a/mesalib/src/glsl/link_uniform_initializers.cpp b/mesalib/src/glsl/link_uniform_initializers.cpp
index d755cec98..c6fe6a9ad 100644
--- a/mesalib/src/glsl/link_uniform_initializers.cpp
+++ b/mesalib/src/glsl/link_uniform_initializers.cpp
@@ -242,8 +242,8 @@ link_set_uniform_initializers(struct gl_shader_program *prog)
if (shader == NULL)
continue;
- foreach_list(node, shader->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, shader->ir) {
+ ir_variable *const var = node->as_variable();
if (!var || var->data.mode != ir_var_uniform)
continue;
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index 5dcb7b571..0e6eb50ef 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -702,8 +702,8 @@ link_cross_validate_uniform_block(void *mem_ctx,
static void
link_update_uniform_buffer_variables(struct gl_shader *shader)
{
- foreach_list(node, shader->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, shader->ir) {
+ ir_variable *const var = node->as_variable();
if ((var == NULL) || !var->is_in_uniform_block())
continue;
@@ -804,8 +804,8 @@ link_set_image_access_qualifiers(struct gl_shader_program *prog)
if (sh == NULL)
continue;
- foreach_list(node, sh->ir) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
if (var && var->data.mode == ir_var_uniform &&
var->type->contains_image()) {
@@ -871,8 +871,8 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
*/
uniform_size.start_shader();
- foreach_list(node, sh->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *const var = node->as_variable();
if ((var == NULL) || (var->data.mode != ir_var_uniform))
continue;
@@ -923,8 +923,8 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
parcel.start_shader((gl_shader_stage)i);
- foreach_list(node, prog->_LinkedShaders[i]->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
+ ir_variable *const var = node->as_variable();
if ((var == NULL) || (var->data.mode != ir_var_uniform))
continue;
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp
index 520a51a27..a3fc2ae34 100644
--- a/mesalib/src/glsl/link_varyings.cpp
+++ b/mesalib/src/glsl/link_varyings.cpp
@@ -175,8 +175,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
/* Find all shader outputs in the "producer" stage.
*/
- foreach_list(node, producer->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, producer->ir) {
+ ir_variable *const var = node->as_variable();
if ((var == NULL) || (var->data.mode != ir_var_shader_out))
continue;
@@ -212,8 +212,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
* should be arrays and the type of the array element should match the type
* of the corresponding producer output.
*/
- foreach_list(node, consumer->ir) {
- ir_variable *const input = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, consumer->ir) {
+ ir_variable *const input = node->as_variable();
if ((input == NULL) || (input->data.mode != ir_var_shader_in))
continue;
@@ -1121,8 +1121,8 @@ populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
0,
sizeof(consumer_inputs_with_locations[0]) * VARYING_SLOT_MAX);
- foreach_list(node, ir) {
- ir_variable *const input_var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ ir_variable *const input_var = node->as_variable();
if ((input_var != NULL) && (input_var->data.mode == ir_var_shader_in)) {
if (input_var->type->is_interface())
@@ -1227,8 +1227,8 @@ canonicalize_shader_io(exec_list *ir, enum ir_variable_mode io_mode)
ir_variable *var_table[MAX_PROGRAM_OUTPUTS * 4];
unsigned num_variables = 0;
- foreach_list(node, ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ ir_variable *const var = node->as_variable();
if (var == NULL || var->data.mode != io_mode)
continue;
@@ -1339,9 +1339,8 @@ assign_varying_locations(struct gl_context *ctx,
}
if (producer) {
- foreach_list(node, producer->ir) {
- ir_variable *const output_var =
- ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, producer->ir) {
+ ir_variable *const output_var = node->as_variable();
if ((output_var == NULL) ||
(output_var->data.mode != ir_var_shader_out))
@@ -1383,9 +1382,8 @@ assign_varying_locations(struct gl_context *ctx,
* geometry) shader program. This means that locations must be assigned
* for all the inputs.
*/
- foreach_list(node, consumer->ir) {
- ir_variable *const input_var =
- ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, consumer->ir) {
+ ir_variable *const input_var = node->as_variable();
if ((input_var == NULL) ||
(input_var->data.mode != ir_var_shader_in))
@@ -1450,8 +1448,8 @@ assign_varying_locations(struct gl_context *ctx,
}
if (consumer && producer) {
- foreach_list(node, consumer->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, consumer->ir) {
+ ir_variable *const var = node->as_variable();
if (var && var->data.mode == ir_var_shader_in &&
var->data.is_unmatched_generic_inout) {
@@ -1494,8 +1492,8 @@ check_against_output_limit(struct gl_context *ctx,
{
unsigned output_vectors = 0;
- foreach_list(node, producer->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, producer->ir) {
+ ir_variable *const var = node->as_variable();
if (var && var->data.mode == ir_var_shader_out &&
var_counts_against_varying_limit(producer->Stage, var)) {
@@ -1533,8 +1531,8 @@ check_against_input_limit(struct gl_context *ctx,
{
unsigned input_vectors = 0;
- foreach_list(node, consumer->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, consumer->ir) {
+ ir_variable *const var = node->as_variable();
if (var && var->data.mode == ir_var_shader_in &&
var_counts_against_varying_limit(consumer->Stage, var)) {
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 3036ebcb3..d588bc63e 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -437,8 +437,8 @@ parse_program_resource_name(const GLchar *name,
void
link_invalidate_variable_locations(exec_list *ir)
{
- foreach_list(node, ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ ir_variable *const var = node->as_variable();
if (var == NULL)
continue;
@@ -692,8 +692,8 @@ cross_validate_globals(struct gl_shader_program *prog,
if (shader_list[i] == NULL)
continue;
- foreach_list(node, shader_list[i]->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
+ ir_variable *const var = node->as_variable();
if (var == NULL)
continue;
@@ -962,8 +962,7 @@ populate_symbol_table(gl_shader *sh)
{
sh->symbols = new(sh) glsl_symbol_table;
- foreach_list(node, sh->ir) {
- ir_instruction *const inst = (ir_instruction *) node;
+ foreach_in_list(ir_instruction, inst, sh->ir) {
ir_variable *var;
ir_function *func;
@@ -1079,9 +1078,7 @@ move_non_declarations(exec_list *instructions, exec_node *last,
temps = hash_table_ctor(0, hash_table_pointer_hash,
hash_table_pointer_compare);
- foreach_list_safe(node, instructions) {
- ir_instruction *inst = (ir_instruction *) node;
-
+ foreach_in_list_safe(ir_instruction, inst, instructions) {
if (inst->as_function())
continue;
@@ -1603,8 +1600,8 @@ link_intrastage_shaders(void *mem_ctx,
* across all shaders.
*/
for (unsigned i = 0; i < (num_shaders - 1); i++) {
- foreach_list(node, shader_list[i]->ir) {
- ir_function *const f = ((ir_instruction *) node)->as_function();
+ foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
+ ir_function *const f = node->as_function();
if (f == NULL)
continue;
@@ -1619,9 +1616,7 @@ link_intrastage_shaders(void *mem_ctx,
if (other == NULL)
continue;
- foreach_list(n, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) n;
-
+ foreach_in_list(ir_function_signature, sig, &f->signatures) {
if (!sig->is_defined || sig->is_builtin())
continue;
@@ -1735,8 +1730,7 @@ link_intrastage_shaders(void *mem_ctx,
if (linked->Stage == MESA_SHADER_GEOMETRY) {
unsigned num_vertices = vertices_per_prim(prog->Geom.InputType);
geom_array_resize_visitor input_resize_visitor(num_vertices, prog);
- foreach_list(n, linked->ir) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, linked->ir) {
ir->accept(&input_resize_visitor);
}
}
@@ -1774,8 +1768,8 @@ update_array_sizes(struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
- foreach_list(node, prog->_LinkedShaders[i]->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
+ ir_variable *const var = node->as_variable();
if ((var == NULL) || (var->data.mode != ir_var_uniform) ||
!var->type->is_array())
@@ -1797,8 +1791,8 @@ update_array_sizes(struct gl_shader_program *prog)
if (prog->_LinkedShaders[j] == NULL)
continue;
- foreach_list(node2, prog->_LinkedShaders[j]->ir) {
- ir_variable *other_var = ((ir_instruction *) node2)->as_variable();
+ foreach_in_list(ir_instruction, node2, prog->_LinkedShaders[j]->ir) {
+ ir_variable *other_var = node2->as_variable();
if (!other_var)
continue;
@@ -1940,8 +1934,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
unsigned num_attr = 0;
- foreach_list(node, sh->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *const var = node->as_variable();
if ((var == NULL) || (var->data.mode != (unsigned) direction))
continue;
@@ -2159,8 +2153,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
void
demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
{
- foreach_list(node, sh->ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *const var = node->as_variable();
if ((var == NULL) || (var->data.mode != int(mode)))
continue;
@@ -2195,8 +2189,8 @@ store_fragdepth_layout(struct gl_shader_program *prog)
* We're only interested in the cases where the variable is NOT removed
* from the IR.
*/
- foreach_list(node, ir) {
- ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ ir_variable *const var = node->as_variable();
if (var == NULL || var->data.mode != ir_var_shader_out) {
continue;
@@ -2327,8 +2321,8 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
total_image_units += sh->NumImages;
if (i == MESA_SHADER_FRAGMENT) {
- foreach_list(node, sh->ir) {
- ir_variable *var = ((ir_instruction *)node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
if (var && var->data.mode == ir_var_shader_out)
fragment_outputs += var->type->count_attribute_slots();
}
@@ -2440,8 +2434,8 @@ check_explicit_uniform_locations(struct gl_context *ctx,
if (!sh)
continue;
- foreach_list(node, sh->ir) {
- ir_variable *var = ((ir_instruction *)node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
if ((var && var->data.mode == ir_var_uniform) &&
var->data.explicit_location) {
if (!reserve_explicit_locations(prog, uniform_map, var))
diff --git a/mesalib/src/glsl/list.h b/mesalib/src/glsl/list.h
index fa6ec12cc..0cffaee7b 100644
--- a/mesalib/src/glsl/list.h
+++ b/mesalib/src/glsl/list.h
@@ -568,19 +568,30 @@ inline void exec_node::insert_before(exec_list *before)
}
#endif
+#define foreach_in_list(__type, __inst, __list) \
+ for (__type *(__inst) = (__type *)(__list)->head; \
+ !(__inst)->is_tail_sentinel(); \
+ (__inst) = (__type *)(__inst)->next)
+
+#define foreach_in_list_reverse(__type, __inst, __list) \
+ for (__type *(__inst) = (__type *)(__list)->head; \
+ !(__inst)->is_head_sentinel(); \
+ (__inst) = (__type *)(__inst)->prev)
+
/**
* This version is safe even if the current node is removed.
*/
-#define foreach_list_safe(__node, __list) \
- for (struct exec_node * __node = (__list)->head, * __next = __node->next \
- ; __next != NULL \
- ; __node = __next, __next = __next->next)
-
-#define foreach_list(__node, __list) \
- for (struct exec_node * __node = (__list)->head \
- ; (__node)->next != NULL \
- ; (__node) = (__node)->next)
-
+#define foreach_in_list_safe(__type, __node, __list) \
+ for (__type *__node = (__type *)(__list)->head, \
+ *__next = (__type *)__node->next; \
+ __next != NULL; \
+ __node = __next, __next = (__type *)__next->next)
+
+#define foreach_in_list_use_after(__type, __inst, __list) \
+ __type *(__inst); \
+ for ((__inst) = (__type *)(__list)->head; \
+ !(__inst)->is_tail_sentinel(); \
+ (__inst) = (__type *)(__inst)->next)
/**
* Iterate through two lists at once. Stops at the end of the shorter list.
*
@@ -597,21 +608,19 @@ inline void exec_node::insert_before(exec_list *before)
__next1 = __next1->next, \
__next2 = __next2->next)
-#define foreach_list_const(__node, __list) \
- for (const struct exec_node * __node = (__list)->head \
- ; (__node)->next != NULL \
- ; (__node) = (__node)->next)
-
#define foreach_list_typed(__type, __node, __field, __list) \
for (__type * __node = \
exec_node_data(__type, (__list)->head, __field); \
(__node)->__field.next != NULL; \
(__node) = exec_node_data(__type, (__node)->__field.next, __field))
-#define foreach_list_typed_const(__type, __node, __field, __list) \
- for (const __type * __node = \
- exec_node_data(__type, (__list)->head, __field); \
- (__node)->__field.next != NULL; \
- (__node) = exec_node_data(__type, (__node)->__field.next, __field))
+#define foreach_list_typed_safe(__type, __node, __field, __list) \
+ for (__type * __node = \
+ exec_node_data(__type, (__list)->head, __field), \
+ * __next = \
+ exec_node_data(__type, (__node)->__field.next, __field); \
+ __next != NULL; \
+ __node = __next, __next = \
+ exec_node_data(__type, (__next)->__field.next, __field))
#endif /* LIST_CONTAINER_H */
diff --git a/mesalib/src/glsl/loop_analysis.cpp b/mesalib/src/glsl/loop_analysis.cpp
index 78ac30044..21d46ebce 100644
--- a/mesalib/src/glsl/loop_analysis.cpp
+++ b/mesalib/src/glsl/loop_analysis.cpp
@@ -227,8 +227,7 @@ loop_analysis::visit_enter(ir_call *)
/* Mark every loop that we're currently analyzing as containing an ir_call
* (even those at outer nesting levels).
*/
- foreach_list(node, &this->state) {
- loop_variable_state *const ls = (loop_variable_state *) node;
+ foreach_in_list(loop_variable_state, ls, &this->state) {
ls->contains_calls = true;
}
@@ -246,9 +245,7 @@ loop_analysis::visit(ir_dereference_variable *ir)
bool nested = false;
- foreach_list(node, &this->state) {
- loop_variable_state *const ls = (loop_variable_state *) node;
-
+ foreach_in_list(loop_variable_state, ls, &this->state) {
ir_variable *var = ir->variable_referenced();
loop_variable *lv = ls->get_or_insert(var, this->in_assignee);
@@ -288,10 +285,10 @@ loop_analysis::visit_leave(ir_loop *ir)
if (ls->contains_calls)
return visit_continue;
- foreach_list(node, &ir->body_instructions) {
+ foreach_in_list(ir_instruction, node, &ir->body_instructions) {
/* Skip over declarations at the start of a loop.
*/
- if (((ir_instruction *) node)->as_variable())
+ if (node->as_variable())
continue;
ir_if *if_stmt = ((ir_instruction *) node)->as_if();
@@ -303,9 +300,7 @@ loop_analysis::visit_leave(ir_loop *ir)
}
- foreach_list_safe(node, &ls->variables) {
- loop_variable *lv = (loop_variable *) node;
-
+ foreach_in_list_safe(loop_variable, lv, &ls->variables) {
/* Move variables that are already marked as being loop constant to
* a separate list. These trivially don't need to be tested.
*/
@@ -333,9 +328,7 @@ loop_analysis::visit_leave(ir_loop *ir)
do {
progress = false;
- foreach_list_safe(node, &ls->variables) {
- loop_variable *lv = (loop_variable *) node;
-
+ foreach_in_list_safe(loop_variable, lv, &ls->variables) {
if (lv->conditional_or_nested_assignment || (lv->num_assignments > 1))
continue;
@@ -359,9 +352,7 @@ loop_analysis::visit_leave(ir_loop *ir)
/* The remaining variables that are not loop invariant might be loop
* induction variables.
*/
- foreach_list_safe(node, &ls->variables) {
- loop_variable *lv = (loop_variable *) node;
-
+ foreach_in_list_safe(loop_variable, lv, &ls->variables) {
/* If there is more than one assignment to a variable, it cannot be a
* loop induction variable. This isn't strictly true, but this is a
* very simple induction variable detector, and it can't handle more
@@ -402,8 +393,7 @@ loop_analysis::visit_leave(ir_loop *ir)
* Also figure out which terminator (if any) produces the smallest
* iteration count--this is the limiting terminator.
*/
- foreach_list(node, &ls->terminators) {
- loop_terminator *t = (loop_terminator *) node;
+ foreach_in_list(loop_terminator, t, &ls->terminators) {
ir_if *if_stmt = t->ir;
/* If-statements can be either 'if (expr)' or 'if (deref)'. We only care
diff --git a/mesalib/src/glsl/loop_controls.cpp b/mesalib/src/glsl/loop_controls.cpp
index 3db06ad18..36b49eb46 100644
--- a/mesalib/src/glsl/loop_controls.cpp
+++ b/mesalib/src/glsl/loop_controls.cpp
@@ -202,9 +202,7 @@ loop_control_visitor::visit_leave(ir_loop *ir)
* bound, then that terminates the loop, so we don't even need the limiting
* terminator.
*/
- foreach_list(node, &ls->terminators) {
- loop_terminator *t = (loop_terminator *) node;
-
+ foreach_in_list(loop_terminator, t, &ls->terminators) {
if (t->iterations < 0)
continue;
diff --git a/mesalib/src/glsl/loop_unroll.cpp b/mesalib/src/glsl/loop_unroll.cpp
index da532804a..ce795f6cd 100644
--- a/mesalib/src/glsl/loop_unroll.cpp
+++ b/mesalib/src/glsl/loop_unroll.cpp
@@ -347,10 +347,8 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
return visit_continue;
}
- foreach_list(node, &ir->body_instructions) {
- /* recognize loops in the form produced by ir_lower_jumps */
- ir_instruction *cur_ir = (ir_instruction *) node;
-
+ /* recognize loops in the form produced by ir_lower_jumps */
+ foreach_in_list(ir_instruction, cur_ir, &ir->body_instructions) {
/* Skip the limiting terminator, since it will go away when we
* unroll.
*/
diff --git a/mesalib/src/glsl/lower_discard.cpp b/mesalib/src/glsl/lower_discard.cpp
index f2757d120..b44d2a6d2 100644
--- a/mesalib/src/glsl/lower_discard.cpp
+++ b/mesalib/src/glsl/lower_discard.cpp
@@ -138,8 +138,8 @@ lower_discard(exec_list *instructions)
static ir_discard *
find_discard(exec_list &instructions)
{
- foreach_list(n, &instructions) {
- ir_discard *ir = ((ir_instruction *) n)->as_discard();
+ foreach_in_list(ir_instruction, node, &instructions) {
+ ir_discard *ir = node->as_discard();
if (ir != NULL)
return ir;
}
diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
index f15b217e0..3232ce92a 100644
--- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp
+++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
@@ -116,9 +116,7 @@ move_block_to_cond_assign(void *mem_ctx,
exec_list *instructions,
struct hash_table *ht)
{
- foreach_list_safe(node, instructions) {
- ir_instruction *ir = (ir_instruction *) node;
-
+ foreach_in_list_safe(ir_instruction, ir, instructions) {
if (ir->ir_type == ir_type_assignment) {
ir_assignment *assign = (ir_assignment *)ir;
@@ -178,12 +176,10 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
ir_assignment *assign;
/* Check that both blocks don't contain anything we can't support. */
- foreach_list(n, &ir->then_instructions) {
- ir_instruction *then_ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, then_ir, &ir->then_instructions) {
visit_tree(then_ir, check_control_flow, &found_control_flow);
}
- foreach_list(n, &ir->else_instructions) {
- ir_instruction *else_ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, else_ir, &ir->else_instructions) {
visit_tree(else_ir, check_control_flow, &found_control_flow);
}
if (found_control_flow)
diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp
index 02f65f097..ec7a0c537 100644
--- a/mesalib/src/glsl/lower_jumps.cpp
+++ b/mesalib/src/glsl/lower_jumps.cpp
@@ -500,16 +500,16 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
/* Note: since visiting a node may change that node's next
* pointer, we can't use visit_exec_list(), because
* visit_exec_list() caches the node's next pointer before
- * visiting it. So we use foreach_list() instead.
+ * visiting it. So we use foreach_in_list() instead.
*
- * foreach_list() isn't safe if the node being visited gets
+ * foreach_in_list() isn't safe if the node being visited gets
* removed, but fortunately this visitor doesn't do that.
*/
block_record saved_block = this->block;
this->block = block_record();
- foreach_list(node, list) {
- ((ir_instruction *) node)->accept(this);
+ foreach_in_list(ir_instruction, node, list) {
+ node->accept(this);
}
block_record ret = this->block;
this->block = saved_block;
diff --git a/mesalib/src/glsl/lower_named_interface_blocks.cpp b/mesalib/src/glsl/lower_named_interface_blocks.cpp
index 04e0d36e6..7304c5139 100644
--- a/mesalib/src/glsl/lower_named_interface_blocks.cpp
+++ b/mesalib/src/glsl/lower_named_interface_blocks.cpp
@@ -99,8 +99,8 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
* The interface block variables are stored in the interface_namespace
* hash table so they can be used in the second pass.
*/
- foreach_list_safe(node, instructions) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list_safe(ir_instruction, node, instructions) {
+ ir_variable *var = node->as_variable();
if (!var || !var->is_interface_instance())
continue;
diff --git a/mesalib/src/glsl/lower_packed_varyings.cpp b/mesalib/src/glsl/lower_packed_varyings.cpp
index eda56a97b..c72b80a32 100644
--- a/mesalib/src/glsl/lower_packed_varyings.cpp
+++ b/mesalib/src/glsl/lower_packed_varyings.cpp
@@ -242,8 +242,8 @@ lower_packed_varyings_visitor::lower_packed_varyings_visitor(
void
lower_packed_varyings_visitor::run(exec_list *instructions)
{
- foreach_list (node, instructions) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, instructions) {
+ ir_variable *var = node->as_variable();
if (var == NULL)
continue;
@@ -639,8 +639,7 @@ lower_packed_varyings_gs_splicer::lower_packed_varyings_gs_splicer(
ir_visitor_status
lower_packed_varyings_gs_splicer::visit_leave(ir_emit_vertex *ev)
{
- foreach_list(node, this->instructions) {
- ir_instruction *ir = (ir_instruction *) node;
+ foreach_in_list(ir_instruction, ir, this->instructions) {
ev->insert_before(ir->clone(this->mem_ctx, NULL));
}
return visit_continue;
diff --git a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp
index fe6a3f208..0c3394a50 100644
--- a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp
+++ b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp
@@ -197,8 +197,7 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
ir_visitor_status
ir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir)
{
- foreach_list_safe(n, &ir->actual_parameters) {
- ir_rvalue *param = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) {
ir_rvalue *new_param = convert_vector_extract_to_cond_assign(param);
if (new_param != param) {
diff --git a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp
index b5bb00c30..4d4d2f17e 100644
--- a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp
+++ b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp
@@ -131,8 +131,7 @@ ir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir)
ir_visitor_status
ir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir)
{
- foreach_list_safe(n, &ir->actual_parameters) {
- ir_rvalue *param = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) {
ir_rvalue *new_param = convert_vector_extract_to_swizzle(param);
if (new_param != param) {
diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp
index 97d3a57e9..ebb076b22 100644
--- a/mesalib/src/glsl/opt_array_splitting.cpp
+++ b/mesalib/src/glsl/opt_array_splitting.cpp
@@ -135,8 +135,7 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var)
if (var->type->is_unsized_array())
return NULL;
- foreach_list(n, &this->variable_list) {
- variable_entry *entry = (variable_entry *) n;
+ foreach_in_list(variable_entry, entry, &this->variable_list) {
if (entry->var == var)
return entry;
}
@@ -213,8 +212,8 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions,
* declarations, which need to be matched by name across shaders.
*/
if (!linked) {
- foreach_list(node, instructions) {
- ir_variable *var = ((ir_instruction *)node)->as_variable();
+ foreach_in_list(ir_instruction, node, instructions) {
+ ir_variable *var = node->as_variable();
if (var) {
variable_entry *entry = get_variable_entry(var);
if (entry)
@@ -224,9 +223,7 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions,
}
/* Trim out variables we found that we can't split. */
- foreach_list_safe(n, &variable_list) {
- variable_entry *entry = (variable_entry *) n;
-
+ foreach_in_list_safe(variable_entry, entry, &variable_list) {
if (debug) {
printf("array %s@%p: decl %d, split %d\n",
entry->var->name, (void *) entry->var, entry->declaration,
@@ -270,8 +267,7 @@ ir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
{
assert(var);
- foreach_list(n, this->variable_list) {
- variable_entry *entry = (variable_entry *) n;
+ foreach_in_list(variable_entry, entry, this->variable_list) {
if (entry->var == var) {
return entry;
}
@@ -368,8 +364,7 @@ optimize_split_arrays(exec_list *instructions, bool linked)
/* Replace the decls of the arrays to be split with their split
* components.
*/
- foreach_list(n, &refs.variable_list) {
- variable_entry *entry = (variable_entry *) n;
+ foreach_in_list(variable_entry, entry, &refs.variable_list) {
const struct glsl_type *type = entry->var->type;
const struct glsl_type *subtype;
diff --git a/mesalib/src/glsl/opt_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp
index 18f5da689..c334e1276 100644
--- a/mesalib/src/glsl/opt_constant_propagation.cpp
+++ b/mesalib/src/glsl/opt_constant_propagation.cpp
@@ -172,8 +172,7 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue)
channel = i;
}
- foreach_list(n, this->acp) {
- acp_entry *entry = (acp_entry *) n;
+ foreach_in_list(acp_entry, entry, this->acp) {
if (entry->var == deref->var && entry->write_mask & (1 << channel)) {
found = entry;
break;
@@ -317,8 +316,7 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
this->killed_all = false;
/* Populate the initial acp with a constant of the original */
- foreach_list(n, orig_acp) {
- acp_entry *a = (acp_entry *) n;
+ foreach_in_list(acp_entry, a, orig_acp) {
this->acp->push_tail(new(this->mem_ctx) acp_entry(a));
}
@@ -333,8 +331,7 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_list(n, new_kills) {
- kill_entry *k = (kill_entry *) n;
+ foreach_in_list(kill_entry, k, new_kills) {
kill(k->var, k->write_mask);
}
}
@@ -378,8 +375,7 @@ ir_constant_propagation_visitor::visit_enter(ir_loop *ir)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_list(n, new_kills) {
- kill_entry *k = (kill_entry *) n;
+ foreach_in_list(kill_entry, k, new_kills) {
kill(k->var, k->write_mask);
}
@@ -397,9 +393,7 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask)
return;
/* Remove any entries currently in the ACP for this kill. */
- foreach_list_safe(n, this->acp) {
- acp_entry *entry = (acp_entry *) n;
-
+ foreach_in_list_safe(acp_entry, entry, this->acp) {
if (entry->var == var) {
entry->write_mask &= ~write_mask;
if (entry->write_mask == 0)
@@ -410,9 +404,7 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask)
/* Add this writemask of the variable to the list of killed
* variables in this block.
*/
- foreach_list(n, this->kills) {
- kill_entry *entry = (kill_entry *) n;
-
+ foreach_in_list(kill_entry, entry, this->kills) {
if (entry->var == var) {
entry->write_mask |= write_mask;
return;
diff --git a/mesalib/src/glsl/opt_constant_variable.cpp b/mesalib/src/glsl/opt_constant_variable.cpp
index 961b8aa06..7222eb92a 100644
--- a/mesalib/src/glsl/opt_constant_variable.cpp
+++ b/mesalib/src/glsl/opt_constant_variable.cpp
@@ -193,12 +193,10 @@ do_constant_variable_unlinked(exec_list *instructions)
{
bool progress = false;
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, instructions) {
ir_function *f = ir->as_function();
if (f) {
- foreach_list(signode, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) signode;
+ foreach_in_list(ir_function_signature, sig, &f->signatures) {
if (do_constant_variable(&sig->body))
progress = true;
}
diff --git a/mesalib/src/glsl/opt_copy_propagation.cpp b/mesalib/src/glsl/opt_copy_propagation.cpp
index 195cc8baa..5c65af66b 100644
--- a/mesalib/src/glsl/opt_copy_propagation.cpp
+++ b/mesalib/src/glsl/opt_copy_propagation.cpp
@@ -167,9 +167,7 @@ ir_copy_propagation_visitor::visit(ir_dereference_variable *ir)
ir_variable *var = ir->var;
- foreach_list(n, this->acp) {
- acp_entry *entry = (acp_entry *) n;
-
+ foreach_in_list(acp_entry, entry, this->acp) {
if (var == entry->lhs) {
ir->var = entry->rhs;
this->progress = true;
@@ -216,8 +214,7 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions)
this->killed_all = false;
/* Populate the initial acp with a copy of the original */
- foreach_list(n, orig_acp) {
- acp_entry *a = (acp_entry *) n;
+ foreach_in_list(acp_entry, a, orig_acp) {
this->acp->push_tail(new(this->mem_ctx) acp_entry(a->lhs, a->rhs));
}
@@ -232,8 +229,7 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_list(n, new_kills) {
- kill_entry *k = (kill_entry *) n;
+ foreach_in_list(kill_entry, k, new_kills) {
kill(k->var);
}
}
@@ -276,8 +272,7 @@ ir_copy_propagation_visitor::visit_enter(ir_loop *ir)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_list(n, new_kills) {
- kill_entry *k = (kill_entry *) n;
+ foreach_in_list(kill_entry, k, new_kills) {
kill(k->var);
}
@@ -291,9 +286,7 @@ ir_copy_propagation_visitor::kill(ir_variable *var)
assert(var != NULL);
/* Remove any entries currently in the ACP for this kill. */
- foreach_list_safe(n, acp) {
- acp_entry *entry = (acp_entry *) n;
-
+ foreach_in_list_safe(acp_entry, entry, acp) {
if (entry->lhs == var || entry->rhs == var) {
entry->remove();
}
diff --git a/mesalib/src/glsl/opt_copy_propagation_elements.cpp b/mesalib/src/glsl/opt_copy_propagation_elements.cpp
index 4d8f476a8..f5f59b7d3 100644
--- a/mesalib/src/glsl/opt_copy_propagation_elements.cpp
+++ b/mesalib/src/glsl/opt_copy_propagation_elements.cpp
@@ -244,9 +244,7 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir)
/* Try to find ACP entries covering swizzle_chan[], hoping they're
* the same source variable.
*/
- foreach_list(n, this->acp) {
- acp_entry *entry = (acp_entry *) n;
-
+ foreach_in_list(acp_entry, entry, this->acp) {
if (var == entry->lhs) {
for (int c = 0; c < chans; c++) {
if (entry->write_mask & (1 << swizzle_chan[c])) {
@@ -324,8 +322,7 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions)
this->killed_all = false;
/* Populate the initial acp with a copy of the original */
- foreach_list(n, orig_acp) {
- acp_entry *a = (acp_entry *) n;
+ foreach_in_list(acp_entry, a, orig_acp) {
this->acp->push_tail(new(this->mem_ctx) acp_entry(a));
}
@@ -343,8 +340,7 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions)
/* Move the new kills into the parent block's list, removing them
* from the parent's ACP list in the process.
*/
- foreach_list_safe(node, new_kills) {
- kill_entry *k = (kill_entry *)node;
+ foreach_in_list_safe(kill_entry, k, new_kills) {
kill(k);
}
}
@@ -387,8 +383,7 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_list_safe(node, new_kills) {
- kill_entry *k = (kill_entry *)node;
+ foreach_in_list_safe(kill_entry, k, new_kills) {
kill(k);
}
@@ -400,9 +395,7 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir)
void
ir_copy_propagation_elements_visitor::kill(kill_entry *k)
{
- foreach_list_safe(node, acp) {
- acp_entry *entry = (acp_entry *)node;
-
+ foreach_in_list_safe(acp_entry, entry, acp) {
if (entry->lhs == k->var) {
entry->write_mask = entry->write_mask & ~k->write_mask;
if (entry->write_mask == 0) {
diff --git a/mesalib/src/glsl/opt_cse.cpp b/mesalib/src/glsl/opt_cse.cpp
index 1b8782bcb..0e720cc26 100644
--- a/mesalib/src/glsl/opt_cse.cpp
+++ b/mesalib/src/glsl/opt_cse.cpp
@@ -173,9 +173,7 @@ dump_ae(exec_list *ae)
int i = 0;
printf("CSE: AE contents:\n");
- foreach_list(node, ae) {
- ae_entry *entry = (ae_entry *)node;
-
+ foreach_in_list(ae_entry, entry, ae) {
printf("CSE: AE %2d (%p): ", i, entry);
(*entry->val)->print();
printf("\n");
@@ -254,9 +252,7 @@ is_cse_candidate(ir_rvalue *ir)
ir_rvalue *
cse_visitor::try_cse(ir_rvalue *rvalue)
{
- foreach_list(node, ae) {
- ae_entry *entry = (ae_entry *)node;
-
+ foreach_in_list(ae_entry, entry, ae) {
if (debug) {
printf("Comparing to AE %p: ", entry);
(*entry->val)->print();
@@ -303,8 +299,7 @@ cse_visitor::try_cse(ir_rvalue *rvalue)
* updated so that any further elimination from inside gets its new
* assignments put before our new assignment.
*/
- foreach_list(fixup_node, ae) {
- ae_entry *fixup_entry = (ae_entry *)fixup_node;
+ foreach_in_list(ae_entry, fixup_entry, ae) {
if (contains_rvalue(assignment->rhs, *fixup_entry->val))
fixup_entry->base_ir = assignment;
}
diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp
index af53d94fd..da90bfb40 100644
--- a/mesalib/src/glsl/opt_dead_code.cpp
+++ b/mesalib/src/glsl/opt_dead_code.cpp
@@ -129,12 +129,10 @@ do_dead_code_unlinked(exec_list *instructions)
{
bool progress = false;
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, instructions) {
ir_function *f = ir->as_function();
if (f) {
- foreach_list(signode, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) signode;
+ foreach_in_list(ir_function_signature, sig, &f->signatures) {
/* The setting of the uniform_locations_assigned flag here is
* irrelevent. If there is a uniform declaration encountered
* inside the body of the function, something has already gone
diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp
index 88895fb0e..4770fcff2 100644
--- a/mesalib/src/glsl/opt_dead_code_local.cpp
+++ b/mesalib/src/glsl/opt_dead_code_local.cpp
@@ -70,9 +70,7 @@ public:
void use_channels(ir_variable *const var, int used)
{
- foreach_list_safe(n, this->assignments) {
- assignment_entry *entry = (assignment_entry *) n;
-
+ foreach_in_list_safe(assignment_entry, entry, this->assignments) {
if (entry->lhs == var) {
if (var->type->is_scalar() || var->type->is_vector()) {
if (debug)
@@ -119,8 +117,7 @@ public:
/* For the purpose of dead code elimination, emitting a vertex counts as
* "reading" all of the currently assigned output variables.
*/
- foreach_list_safe(n, this->assignments) {
- assignment_entry *entry = (assignment_entry *) n;
+ foreach_in_list_safe(assignment_entry, entry, this->assignments) {
if (entry->lhs->data.mode == ir_var_shader_out) {
if (debug)
printf("kill %s\n", entry->lhs->name);
@@ -196,9 +193,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments)
printf("looking for %s.0x%01x to remove\n", var->name,
ir->write_mask);
- foreach_list_safe(n, assignments) {
- assignment_entry *entry = (assignment_entry *) n;
-
+ foreach_in_list_safe(assignment_entry, entry, assignments) {
if (entry->lhs != var)
continue;
@@ -258,9 +253,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments)
*/
if (debug)
printf("looking for %s to remove\n", var->name);
- foreach_list_safe(n, assignments) {
- assignment_entry *entry = (assignment_entry *) n;
-
+ foreach_in_list_safe(assignment_entry, entry, assignments) {
if (entry->lhs == var) {
if (debug)
printf("removing %s\n", var->name);
@@ -280,9 +273,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments)
printf("add %s\n", var->name);
printf("current entries\n");
- foreach_list(n, assignments) {
- assignment_entry *entry = (assignment_entry *) n;
-
+ foreach_in_list(assignment_entry, entry, assignments) {
printf(" %s (0x%01x)\n", entry->lhs->name, entry->unused);
}
}
diff --git a/mesalib/src/glsl/opt_dead_functions.cpp b/mesalib/src/glsl/opt_dead_functions.cpp
index 8bb278e45..5dff16521 100644
--- a/mesalib/src/glsl/opt_dead_functions.cpp
+++ b/mesalib/src/glsl/opt_dead_functions.cpp
@@ -74,8 +74,7 @@ public:
signature_entry *
ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig)
{
- foreach_list(n, &this->signature_list) {
- signature_entry *entry = (signature_entry *) n;
+ foreach_in_list(signature_entry, entry, &this->signature_list) {
if (entry->signature == sig)
return entry;
}
@@ -123,9 +122,7 @@ do_dead_functions(exec_list *instructions)
* the unused ones, and remove function definitions that have no more
* signatures.
*/
- foreach_list_safe(n, &v.signature_list) {
- signature_entry *entry = (signature_entry *) n;
-
+ foreach_in_list_safe(signature_entry, entry, &v.signature_list) {
if (!entry->used) {
entry->signature->remove();
delete entry->signature;
@@ -137,8 +134,7 @@ do_dead_functions(exec_list *instructions)
/* We don't just do this above when we nuked a signature because of
* const pointers.
*/
- foreach_list_safe(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list_safe(ir_instruction, ir, instructions) {
ir_function *func = ir->as_function();
if (func && func->signatures.is_empty()) {
diff --git a/mesalib/src/glsl/opt_flip_matrices.cpp b/mesalib/src/glsl/opt_flip_matrices.cpp
index 9044fd680..04c6170b8 100644
--- a/mesalib/src/glsl/opt_flip_matrices.cpp
+++ b/mesalib/src/glsl/opt_flip_matrices.cpp
@@ -45,8 +45,7 @@ public:
mvp_transpose = NULL;
texmat_transpose = NULL;
- foreach_list(n, instructions) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, instructions) {
ir_variable *var = ir->as_variable();
if (!var)
continue;
diff --git a/mesalib/src/glsl/opt_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp
index 9649598dd..b84bb8e11 100644
--- a/mesalib/src/glsl/opt_function_inlining.cpp
+++ b/mesalib/src/glsl/opt_function_inlining.cpp
@@ -107,7 +107,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare);
num_parameters = 0;
- foreach_list(n, &this->callee->parameters)
+ foreach_in_list(ir_rvalue, param, &this->callee->parameters)
num_parameters++;
parameters = new ir_variable *[num_parameters];
@@ -159,8 +159,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
exec_list new_instructions;
/* Generate the inlined body of the function to a new list */
- foreach_list(n, &callee->body) {
- ir_instruction *ir = (ir_instruction *) n;
+ foreach_in_list(ir_instruction, ir, &callee->body) {
ir_instruction *new_ir = ir->clone(ctx, ht);
new_instructions.push_tail(new_ir);
@@ -342,8 +341,7 @@ ir_variable_replacement_visitor::visit_leave(ir_dereference_record *ir)
ir_visitor_status
ir_variable_replacement_visitor::visit_leave(ir_call *ir)
{
- foreach_list_safe(n, &ir->actual_parameters) {
- ir_rvalue *param = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) {
ir_rvalue *new_param = param;
replace_rvalue(&new_param);
diff --git a/mesalib/src/glsl/opt_structure_splitting.cpp b/mesalib/src/glsl/opt_structure_splitting.cpp
index 1ec537b13..5e82fe93a 100644
--- a/mesalib/src/glsl/opt_structure_splitting.cpp
+++ b/mesalib/src/glsl/opt_structure_splitting.cpp
@@ -107,8 +107,7 @@ ir_structure_reference_visitor::get_variable_entry(ir_variable *var)
|| var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out)
return NULL;
- foreach_list(n, &this->variable_list) {
- variable_entry *entry = (variable_entry *) n;
+ foreach_in_list(variable_entry, entry, &this->variable_list) {
if (entry->var == var)
return entry;
}
@@ -209,8 +208,7 @@ ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var)
if (!var->type->is_record())
return NULL;
- foreach_list(n, this->variable_list) {
- variable_entry *entry = (variable_entry *) n;
+ foreach_in_list(variable_entry, entry, this->variable_list) {
if (entry->var == var) {
return entry;
}
@@ -315,9 +313,7 @@ do_structure_splitting(exec_list *instructions)
visit_list_elements(&refs, instructions);
/* Trim out variables we can't split. */
- foreach_list_safe(n, &refs.variable_list) {
- variable_entry *entry = (variable_entry *) n;
-
+ foreach_in_list_safe(variable_entry, entry, &refs.variable_list) {
if (debug) {
printf("structure %s@%p: decl %d, whole_access %d\n",
entry->var->name, (void *) entry->var, entry->declaration,
@@ -337,8 +333,7 @@ do_structure_splitting(exec_list *instructions)
/* Replace the decls of the structures to be split with their split
* components.
*/
- foreach_list_safe(n, &refs.variable_list) {
- variable_entry *entry = (variable_entry *) n;
+ foreach_in_list_safe(variable_entry, entry, &refs.variable_list) {
const struct glsl_type *type = entry->var->type;
entry->mem_ctx = ralloc_parent(entry->var);
diff --git a/mesalib/src/glsl/opt_vectorize.cpp b/mesalib/src/glsl/opt_vectorize.cpp
index f9a3b6183..28534a86a 100644
--- a/mesalib/src/glsl/opt_vectorize.cpp
+++ b/mesalib/src/glsl/opt_vectorize.cpp
@@ -227,8 +227,7 @@ write_mask_to_swizzle(unsigned write_mask)
case WRITEMASK_Z: return SWIZZLE_Z;
case WRITEMASK_W: return SWIZZLE_W;
}
- assert(!"not reached");
- unreachable();
+ unreachable("not reached");
}
/**
diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp
index 6906ff0eb..1a28e1d52 100644
--- a/mesalib/src/glsl/s_expression.cpp
+++ b/mesalib/src/glsl/s_expression.cpp
@@ -162,8 +162,7 @@ void s_symbol::print()
void s_list::print()
{
printf("(");
- foreach_list(n, &this->subexpressions) {
- s_expression *expr = (s_expression *) n;
+ foreach_in_list(s_expression, expr, &this->subexpressions) {
expr->print();
if (!expr->next->is_tail_sentinel())
printf(" ");
@@ -201,11 +200,10 @@ s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial)
return false;
unsigned i = 0;
- foreach_list(node, &list->subexpressions) {
+ foreach_in_list(s_expression, expr, &list->subexpressions) {
if (i >= n)
return partial; /* More actual items than the pattern expected */
- s_expression *expr = (s_expression *) node;
if (expr == NULL || !pattern[i].match(expr))
return false;
diff --git a/mesalib/src/loader/Makefile.am b/mesalib/src/loader/Makefile.am
index ae8a84492..c02de6f59 100755
--- a/mesalib/src/loader/Makefile.am
+++ b/mesalib/src/loader/Makefile.am
@@ -33,6 +33,7 @@ libloader_la_SOURCES = $(LOADER_C_FILES)
libloader_la_LIBADD =
if NEED_OPENGL_COMMON
+if HAVE_DRICOMMON
libloader_la_CPPFLAGS += \
-I$(top_srcdir)/src/mesa/drivers/dri/common/ \
-I$(top_builddir)/src/mesa/drivers/dri/common/ \
@@ -47,6 +48,7 @@ libloader_la_LIBADD += \
-lm \
$(EXPAT_LIBS)
endif
+endif
if !HAVE_LIBDRM
libloader_la_CPPFLAGS += \
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index f313f5645..f1f57297c 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -2592,8 +2592,7 @@ _mesa_meta_setup_texture_coords(GLenum faceTarget,
coord = coords3;
break;
default:
- assert(0);
- unreachable();
+ unreachable("not reached");
}
coord[3] = (float) (slice / 6);
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index f4707c483..f18fac61e 100755
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -681,7 +681,7 @@ dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
static int
-dri2ConfigQueryb(__DRIscreen *screen, const char *var, bool *val)
+dri2ConfigQueryb(__DRIscreen *screen, const char *var, unsigned char *val)
{
if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
return -1;
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
index 2639202c4..b129979d2 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
+++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
@@ -312,7 +312,7 @@ strndup(const char *str, size_t size)
#endif /* _WIN32 should be !HAVE_STRNDUP */
/** \brief Parse a value of a given type. */
-static bool parseValue (driOptionValue *v, driOptionType type,
+static unsigned char parseValue (driOptionValue *v, driOptionType type,
const XML_Char *string) {
const XML_Char *tail = NULL;
/* skip leading white-space */
@@ -355,7 +355,7 @@ static bool parseValue (driOptionValue *v, driOptionType type,
}
/** \brief Parse a list of ranges of type info->type. */
-static bool parseRanges (driOptionInfo *info, const XML_Char *string) {
+static unsigned char parseRanges (driOptionInfo *info, const XML_Char *string) {
XML_Char *cp, *range;
uint32_t nRanges, i;
driOptionRange *ranges;
@@ -1030,13 +1030,13 @@ void driDestroyOptionCache (driOptionCache *cache) {
free(cache->values);
}
-bool driCheckOption (const driOptionCache *cache, const char *name,
+unsigned char driCheckOption (const driOptionCache *cache, const char *name,
driOptionType type) {
uint32_t i = findOption (cache, name);
return cache->info[i].name != NULL && cache->info[i].type == type;
}
-bool driQueryOptionb (const driOptionCache *cache, const char *name) {
+unsigned char driQueryOptionb (const driOptionCache *cache, const char *name) {
uint32_t i = findOption (cache, name);
/* make sure the option is defined and has the correct type */
assert (cache->info[i].name != NULL);
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h
index 9cb831571..59a67b328 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h
+++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h
@@ -30,8 +30,6 @@
#ifndef __XMLCONFIG_H
#define __XMLCONFIG_H
-#include <stdbool.h>
-
#define STRING_CONF_MAXLEN 25
/** \brief Option data types */
@@ -41,7 +39,7 @@ typedef enum driOptionType {
/** \brief Option value */
typedef union driOptionValue {
- bool _bool; /**< \brief Boolean */
+ unsigned char _bool; /**< \brief Boolean */
int _int; /**< \brief Integer or Enum */
float _float; /**< \brief Floating-point */
char *_string; /**< \brief String */
@@ -114,11 +112,11 @@ void driDestroyOptionInfo (driOptionCache *info);
void driDestroyOptionCache (driOptionCache *cache);
/** \brief Check if there exists a certain option */
-bool driCheckOption (const driOptionCache *cache, const char *name,
+unsigned char driCheckOption (const driOptionCache *cache, const char *name,
driOptionType type);
/** \brief Query a boolean option value */
-bool driQueryOptionb (const driOptionCache *cache, const char *name);
+unsigned char driQueryOptionb (const driOptionCache *cache, const char *name);
/** \brief Query an integer option value */
int driQueryOptioni (const driOptionCache *cache, const char *name);
/** \brief Query a floating-point option value */
diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h
index 600691724..79d8740e5 100644
--- a/mesalib/src/mesa/main/compiler.h
+++ b/mesalib/src/mesa/main/compiler.h
@@ -253,15 +253,23 @@ static INLINE GLuint CPU_TO_LE32(GLuint x)
* function" warnings.
*/
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 5
-#define unreachable() __builtin_unreachable()
+#define unreachable(str) \
+do { \
+ assert(!str); \
+ __builtin_unreachable(); \
+} while (0)
#elif (defined(__clang__) && defined(__has_builtin))
# if __has_builtin(__builtin_unreachable)
-# define unreachable() __builtin_unreachable()
+# define unreachable(str) \
+do { \
+ assert(!str); \
+ __builtin_unreachable(); \
+} while (0)
# endif
#endif
#ifndef unreachable
-#define unreachable()
+#define unreachable(str)
#endif
/*
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 6f2536170..92e3f0d68 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -323,6 +323,7 @@ static const struct extension extension_table[] = {
{ "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 },
{ "GL_AMD_shader_trinary_minmax", o(dummy_true), GL, 2012 },
{ "GL_AMD_vertex_shader_layer", o(AMD_vertex_shader_layer), GLC, 2012 },
+ { "GL_AMD_vertex_shader_viewport_index", o(AMD_vertex_shader_viewport_index), GLC, 2012 },
{ "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL, 2006 },
{ "GL_APPLE_packed_pixels", o(dummy_true), GLL, 2002 },
{ "GL_APPLE_texture_max_level", o(dummy_true), ES1 | ES2, 2009 },
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index eaf377610..a7126fd55 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -2560,7 +2560,7 @@ struct gl_uniform_block
GLuint Binding;
/**
- * Minimum size of a buffer object to back this uniform buffer
+ * Minimum size (in bytes) of a buffer object to back this uniform buffer
* (GL_UNIFORM_BLOCK_DATA_SIZE).
*/
GLuint UniformBufferSize;
@@ -3616,6 +3616,7 @@ struct gl_extensions
GLboolean AMD_performance_monitor;
GLboolean AMD_seamless_cubemap_per_texture;
GLboolean AMD_vertex_shader_layer;
+ GLboolean AMD_vertex_shader_viewport_index;
GLboolean APPLE_object_purgeable;
GLboolean ATI_texture_compression_3dc;
GLboolean ATI_texture_mirror_once;
diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp
index 36d1d9cc0..426774316 100644
--- a/mesalib/src/mesa/main/shader_query.cpp
+++ b/mesalib/src/mesa/main/shader_query.cpp
@@ -126,8 +126,8 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index,
exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
unsigned current_index = 0;
- foreach_list(node, ir) {
- const ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ const ir_variable *const var = node->as_variable();
if (!is_active_attrib(var))
continue;
@@ -236,8 +236,8 @@ _mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name)
return -1;
exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
- foreach_list(node, ir) {
- const ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ const ir_variable *const var = node->as_variable();
/* The extra check against VERT_ATTRIB_GENERIC0 is because
* glGetAttribLocation cannot be used on "conventional" attributes.
@@ -274,8 +274,8 @@ _mesa_count_active_attribs(struct gl_shader_program *shProg)
exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
unsigned i = 0;
- foreach_list(node, ir) {
- const ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ const ir_variable *const var = node->as_variable();
if (!is_active_attrib(var))
continue;
@@ -298,8 +298,8 @@ _mesa_longest_attribute_name_length(struct gl_shader_program *shProg)
exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
size_t longest = 0;
- foreach_list(node, ir) {
- const ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ const ir_variable *const var = node->as_variable();
if (var == NULL
|| var->data.mode != ir_var_shader_in
@@ -400,8 +400,8 @@ _mesa_GetFragDataIndex(GLuint program, const GLchar *name)
return -1;
exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
- foreach_list(node, ir) {
- const ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ const ir_variable *const var = node->as_variable();
/* The extra check against FRAG_RESULT_DATA0 is because
* glGetFragDataLocation cannot be used on "conventional" attributes.
@@ -456,8 +456,8 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
return -1;
exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
- foreach_list(node, ir) {
- const ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, ir) {
+ const ir_variable *const var = node->as_variable();
/* The extra check against FRAG_RESULT_DATA0 is because
* glGetFragDataLocation cannot be used on "conventional" attributes.
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 59cf1232a..1109051e9 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -663,11 +663,7 @@ ir_to_mesa_visitor::get_temp(const glsl_type *type)
variable_storage *
ir_to_mesa_visitor::find_variable_storage(const ir_variable *var)
{
- variable_storage *entry;
-
- foreach_list(node, &this->variables) {
- entry = (variable_storage *) node;
-
+ foreach_in_list(variable_storage, entry, &this->variables) {
if (entry->var == var)
return entry;
}
@@ -801,9 +797,7 @@ ir_to_mesa_visitor::visit(ir_function *ir)
assert(sig);
- foreach_list(node, &sig->body) {
- ir_instruction *ir = (ir_instruction *) node;
-
+ foreach_in_list(ir_instruction, ir, &sig->body) {
ir->accept(this);
}
}
@@ -1868,8 +1862,7 @@ ir_to_mesa_visitor::visit(ir_constant *ir)
src_reg temp_base = get_temp(ir->type);
dst_reg temp = dst_reg(temp_base);
- foreach_list(node, &ir->components) {
- ir_constant *field_value = (ir_constant *) node;
+ foreach_in_list(ir_constant, field_value, &ir->components) {
int size = type_size(field_value->type);
assert(size > 0);
@@ -2338,9 +2331,7 @@ set_branchtargets(ir_to_mesa_visitor *v,
mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
break;
case OPCODE_CAL:
- foreach_list(n, &v->function_signatures) {
- function_entry *entry = (function_entry *) n;
-
+ foreach_in_list(function_entry, entry, &v->function_signatures) {
if (entry->sig_id == mesa_instructions[i].BranchTarget) {
mesa_instructions[i].BranchTarget = entry->inst;
break;
@@ -2495,8 +2486,8 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
{
add_uniform_to_shader add(shader_program, params, sh->Stage);
- foreach_list(node, sh->ir) {
- ir_variable *var = ((ir_instruction *) node)->as_variable();
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
if ((var == NULL) || (var->data.mode != ir_var_uniform)
|| var->is_in_uniform_block() || (strncmp(var->name, "gl_", 3) == 0))
@@ -2621,9 +2612,7 @@ ir_to_mesa_visitor::copy_propagate(void)
int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
int level = 0;
- foreach_list(node, &this->instructions) {
- ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node;
-
+ foreach_in_list(ir_to_mesa_instruction, inst, &this->instructions) {
assert(inst->dst.file != PROGRAM_TEMPORARY
|| inst->dst.index < this->next_temp);
@@ -2826,7 +2815,7 @@ get_mesa_program(struct gl_context *ctx,
prog->NumTemporaries = v.next_temp;
int num_instructions = 0;
- foreach_list(node, &v.instructions) {
+ foreach_in_list(ir_instruction, node, &v.instructions) {
num_instructions++;
}
@@ -2842,9 +2831,7 @@ get_mesa_program(struct gl_context *ctx,
*/
mesa_inst = mesa_instructions;
i = 0;
- foreach_list(node, &v.instructions) {
- const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node;
-
+ foreach_in_list(const ir_to_mesa_instruction, inst, &v.instructions) {
mesa_inst->Opcode = inst->op;
mesa_inst->CondUpdate = inst->cond_update;
if (inst->saturate)
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
index 02624617b..3b4d28d47 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -225,6 +225,9 @@ st_bufferobj_data(struct gl_context *ctx,
case GL_UNIFORM_BUFFER:
bind = PIPE_BIND_CONSTANT_BUFFER;
break;
+ case GL_DRAW_INDIRECT_BUFFER:
+ bind = PIPE_BIND_COMMAND_ARGS_BUFFER;
+ break;
default:
bind = 0;
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index 371f7fcda..4bfa8d75a 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -136,7 +136,7 @@ set_vertex_shader_layered(struct st_context *st)
struct pipe_context *pipe = st->pipe;
if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) ||
- !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) {
+ !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) {
assert(!"Got layered clear, but the VS layer output is unsupported");
set_vertex_shader(st);
return;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c
index 78a737094..489f537d8 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c
@@ -132,13 +132,13 @@ st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q)
type == PIPE_QUERY_TIMESTAMP) {
/* Determine time elapsed by emitting two timestamp queries. */
if (!stq->pq_begin) {
- stq->pq_begin = pipe->create_query(pipe, type);
+ stq->pq_begin = pipe->create_query(pipe, type, 0);
stq->type = type;
}
pipe->end_query(pipe, stq->pq_begin);
} else {
if (!stq->pq) {
- stq->pq = pipe->create_query(pipe, type);
+ stq->pq = pipe->create_query(pipe, type, q->Stream);
stq->type = type;
}
if (stq->pq) {
@@ -164,7 +164,7 @@ st_EndQuery(struct gl_context *ctx, struct gl_query_object *q)
if ((q->Target == GL_TIMESTAMP ||
q->Target == GL_TIME_ELAPSED) &&
!stq->pq) {
- stq->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP);
+ stq->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP, 0);
stq->type = PIPE_QUERY_TIMESTAMP;
}
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index c8189faad..64d6ef525 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -244,6 +244,14 @@ st_draw_vbo(struct gl_context *ctx,
}
}
+ if (indirect) {
+ info.indirect = st_buffer_object(indirect)->buffer;
+
+ /* Primitive restart is not handled by the VBO module in this case. */
+ info.primitive_restart = ctx->Array._PrimitiveRestart;
+ info.restart_index = ctx->Array.RestartIndex;
+ }
+
/* do actual drawing */
for (i = 0; i < nr_prims; i++) {
info.mode = translate_prim(ctx, prims[i].mode);
@@ -256,6 +264,7 @@ st_draw_vbo(struct gl_context *ctx,
info.min_index = info.start;
info.max_index = info.start + info.count - 1;
}
+ info.indirect_offset = prims[i].indirect_offset;
if (ST_DEBUG & DEBUG_DRAW) {
debug_printf("st/draw: mode %s start %u count %u indexed %d\n",
@@ -265,7 +274,7 @@ st_draw_vbo(struct gl_context *ctx,
info.indexed);
}
- if (info.count_from_stream_output) {
+ if (info.count_from_stream_output || info.indirect) {
cso_draw_vbo(st->cso_context, &info);
}
else if (info.primitive_restart) {
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index e93804689..4207cb64a 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -287,6 +287,11 @@ void st_init_limits(struct st_context *st)
screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS);
c->MaxTransformFeedbackInterleavedComponents =
screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS);
+ c->MaxVertexStreams =
+ MAX2(1, screen->get_param(screen, PIPE_CAP_MAX_VERTEX_STREAMS));
+
+ /* The vertex stream must fit into pipe_stream_output_info::stream */
+ assert(c->MaxVertexStreams <= 4);
c->StripTextureBorder = GL_TRUE;
@@ -427,6 +432,7 @@ void st_init_extensions(struct st_context *st)
{ o(ARB_texture_multisample), PIPE_CAP_TEXTURE_MULTISAMPLE },
{ o(ARB_texture_query_lod), PIPE_CAP_TEXTURE_QUERY_LOD },
{ o(ARB_sample_shading), PIPE_CAP_SAMPLE_SHADING },
+ { o(ARB_draw_indirect), PIPE_CAP_DRAW_INDIRECT }
};
/* Required: render target and sampler support */
@@ -618,7 +624,7 @@ void st_init_extensions(struct st_context *st)
/* This extension needs full OpenGL 3.2, but we don't know if that's
* supported at this point. Only check the GLSL version. */
if (ctx->Const.GLSLVersion >= 150 &&
- screen->get_param(screen, PIPE_CAP_TGSI_VS_LAYER)) {
+ screen->get_param(screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) {
ctx->Extensions.AMD_vertex_shader_layer = GL_TRUE;
}
@@ -809,6 +815,9 @@ void st_init_extensions(struct st_context *st)
ctx->Const.ViewportBounds.Min = -16384.0;
ctx->Const.ViewportBounds.Max = 16384.0;
ctx->Extensions.ARB_viewport_array = GL_TRUE;
+ ctx->Extensions.ARB_fragment_layer_viewport = GL_TRUE;
+ if (ctx->Extensions.AMD_vertex_shader_layer)
+ ctx->Extensions.AMD_vertex_shader_viewport_index = GL_TRUE;
}
}
if (ctx->Const.MaxProgramTextureGatherComponents > 0)
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 cac1e0fe2..9e1943139 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -919,9 +919,7 @@ glsl_to_tgsi_visitor::add_constant(gl_register_file file,
/* Search immediate storage to see if we already have an identical
* immediate that we can use instead of adding a duplicate entry.
*/
- foreach_list(node, &this->immediates) {
- entry = (immediate_storage *) node;
-
+ foreach_in_list(immediate_storage, entry, &this->immediates) {
if (entry->size == size &&
entry->type == datatype &&
!memcmp(entry->values, values, size * sizeof(gl_constant_value))) {
@@ -1061,11 +1059,7 @@ variable_storage *
glsl_to_tgsi_visitor::find_variable_storage(ir_variable *var)
{
- variable_storage *entry;
-
- foreach_list(node, &this->variables) {
- entry = (variable_storage *) node;
-
+ foreach_in_list(variable_storage, entry, &this->variables) {
if (entry->var == var)
return entry;
}
@@ -1202,9 +1196,7 @@ glsl_to_tgsi_visitor::visit(ir_function *ir)
assert(sig);
- foreach_list(node, &sig->body) {
- ir_instruction *ir = (ir_instruction *) node;
-
+ foreach_in_list(ir_instruction, ir, &sig->body) {
ir->accept(this);
}
}
@@ -1971,9 +1963,17 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
assert(ir->type->is_vector() || ir->type->is_scalar());
if (const_offset_ir) {
- index_reg = st_src_reg_for_int(const_offset / 16);
- } else {
- emit(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1], st_src_reg_for_int(4));
+ /* Constant index into constant buffer */
+ cbuf.reladdr = NULL;
+ cbuf.index = const_offset / 16;
+ cbuf.has_index2 = true;
+ }
+ else {
+ /* Relative/variable index into constant buffer */
+ emit(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1],
+ st_src_reg_for_int(4));
+ cbuf.reladdr = ralloc(mem_ctx, st_src_reg);
+ memcpy(cbuf.reladdr, &index_reg, sizeof(index_reg));
}
cbuf.swizzle = swizzle_for_size(ir->type->vector_elements);
@@ -1982,9 +1982,6 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
const_offset % 16 / 4,
const_offset % 16 / 4);
- cbuf.reladdr = ralloc(mem_ctx, st_src_reg);
- memcpy(cbuf.reladdr, &index_reg, sizeof(index_reg));
-
if (ir->type->base_type == GLSL_TYPE_BOOL) {
emit(ir, TGSI_OPCODE_USNE, result_dst, cbuf, st_src_reg_for_int(0));
} else {
@@ -2549,8 +2546,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
st_src_reg temp_base = get_temp(ir->type);
st_dst_reg temp = st_dst_reg(temp_base);
- foreach_list(node, &ir->components) {
- ir_constant *field_value = (ir_constant *) node;
+ foreach_in_list(ir_constant, field_value, &ir->components) {
int size = type_size(field_value->type);
assert(size > 0);
@@ -2664,11 +2660,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
function_entry *
glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig)
{
- function_entry *entry;
-
- foreach_list(node, &this->function_signatures) {
- entry = (function_entry *) node;
-
+ foreach_in_list_use_after(function_entry, entry, &this->function_signatures) {
if (entry->sig == sig)
return entry;
}
@@ -2679,8 +2671,7 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig)
entry->bgn_inst = NULL;
/* Allocate storage for all the parameters. */
- foreach_list(node, &sig->parameters) {
- ir_variable *param = (ir_variable *) node;
+ foreach_in_list(ir_variable, param, &sig->parameters) {
variable_storage *storage;
storage = find_variable_storage(param);
@@ -3139,14 +3130,18 @@ void
glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir)
{
assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);
- emit(ir, TGSI_OPCODE_EMIT);
+
+ ir->stream->accept(this);
+ emit(ir, TGSI_OPCODE_EMIT, undef_dst, this->result);
}
void
glsl_to_tgsi_visitor::visit(ir_end_primitive *ir)
{
assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);
- emit(ir, TGSI_OPCODE_ENDPRIM);
+
+ ir->stream->accept(this);
+ emit(ir, TGSI_OPCODE_ENDPRIM, undef_dst, this->result);
}
glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
@@ -3190,9 +3185,7 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
{
v->samplers_used = 0;
- foreach_list(node, &v->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) {
if (is_tex_instruction(inst->op)) {
v->samplers_used |= 1 << inst->sampler;
@@ -3336,8 +3329,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS);
memset(outputWrites, 0, sizeof(outputWrites));
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
unsigned prevWriteMask = 0;
/* Give up if we encounter relative addressing or flow control. */
@@ -3382,8 +3374,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
void
glsl_to_tgsi_visitor::rename_temp_register(int index, int new_index)
{
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
unsigned j;
for (j=0; j < num_inst_src_regs(inst->op); j++) {
@@ -3413,9 +3404,7 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index)
int loop_start = -1; /* index of the first active BGNLOOP (if any) */
unsigned i = 0, j;
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
for (j=0; j < num_inst_src_regs(inst->op); j++) {
if (inst->src[j].file == PROGRAM_TEMPORARY &&
inst->src[j].index == index) {
@@ -3451,9 +3440,7 @@ glsl_to_tgsi_visitor::get_first_temp_write(int index)
int loop_start = -1; /* index of the first active BGNLOOP (if any) */
int i = 0;
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) {
return (depth == 0) ? i : loop_start;
}
@@ -3480,9 +3467,7 @@ glsl_to_tgsi_visitor::get_last_temp_read(int index)
int last = -1; /* index of last instruction that reads the temporary */
unsigned i = 0, j;
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
for (j=0; j < num_inst_src_regs(inst->op); j++) {
if (inst->src[j].file == PROGRAM_TEMPORARY &&
inst->src[j].index == index) {
@@ -3516,9 +3501,7 @@ glsl_to_tgsi_visitor::get_last_temp_write(int index)
int last = -1; /* index of last instruction that writes to the temporary */
int i = 0;
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index)
last = (depth == 0) ? i : -2;
@@ -3565,9 +3548,7 @@ glsl_to_tgsi_visitor::copy_propagate(void)
int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
int level = 0;
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
assert(inst->dst.file != PROGRAM_TEMPORARY
|| inst->dst.index < this->next_temp);
@@ -3761,9 +3742,7 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void)
int level = 0;
int removed = 0;
- foreach_list(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
assert(inst->dst.file != PROGRAM_TEMPORARY
|| inst->dst.index < this->next_temp);
@@ -3889,9 +3868,7 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void)
/* Now actually remove the instructions that are completely dead and update
* the writemask of other instructions with dead channels.
*/
- foreach_list_safe(node, &this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
-
+ foreach_in_list_safe(glsl_to_tgsi_instruction, inst, &this->instructions) {
if (!inst->dead_mask || !inst->dst.writemask)
continue;
else if ((inst->dst.writemask & ~inst->dead_mask) == 0) {
@@ -4077,8 +4054,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
/* Now copy the instructions from the original glsl_to_tgsi_visitor into the
* new visitor. */
- foreach_list(node, &original->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &original->instructions) {
glsl_to_tgsi_instruction *newinst;
st_src_reg src_regs[3];
@@ -4162,8 +4138,7 @@ get_bitmap_visitor(struct st_fragment_program *fp,
/* Now copy the instructions from the original glsl_to_tgsi_visitor into the
* new visitor. */
- foreach_list(node, &original->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &original->instructions) {
glsl_to_tgsi_instruction *newinst;
st_src_reg src_regs[3];
@@ -4396,7 +4371,7 @@ src_register(struct st_translate *t,
case PROGRAM_CONSTANT: /* ie, immediate */
if (index2D) {
struct ureg_src src;
- src = ureg_src_register(TGSI_FILE_CONSTANT, 0);
+ src = ureg_src_register(TGSI_FILE_CONSTANT, index);
src.Dimension = 1;
src.DimensionIndex = index2D;
return src;
@@ -4484,7 +4459,10 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
{
struct ureg_src src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D);
- if (t->procType == TGSI_PROCESSOR_GEOMETRY && src_reg->has_index2) {
+ if (src_reg->has_index2) {
+ /* 2D indexes occur with geometry shader inputs (attrib, vertex)
+ * and UBO constant buffers (buffer, position).
+ */
src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D);
if (src_reg->reladdr2)
src = ureg_src_dimension_indirect(src, ureg_src(t->address[1]),
@@ -5115,7 +5093,14 @@ st_translate_program(
unsigned num_ubos = program->shader->NumUniformBlocks;
for (i = 0; i < num_ubos; i++) {
- ureg_DECL_constant2D(t->ureg, 0, program->shader->UniformBlocks[i].UniformBufferSize / 4, i + 1);
+ unsigned size =
+ program->shader_program->UniformBlocks[i].UniformBufferSize;
+ unsigned num_const_vecs = (size + 15) / 16;
+ unsigned first, last;
+ assert(num_const_vecs > 0);
+ first = 0;
+ last = num_const_vecs > 0 ? num_const_vecs - 1 : 0;
+ ureg_DECL_constant2D(t->ureg, first, last, i + 1);
}
}
@@ -5128,8 +5113,7 @@ st_translate_program(
goto out;
}
i = 0;
- foreach_list(node, &program->immediates) {
- immediate_storage *imm = (immediate_storage *) node;
+ foreach_in_list(immediate_storage, imm, &program->immediates) {
assert(i < program->num_immediates);
t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size);
}
@@ -5144,9 +5128,9 @@ st_translate_program(
/* Emit each instruction in turn:
*/
- foreach_list(n, &program->instructions) {
+ foreach_in_list(glsl_to_tgsi_instruction, inst, &program->instructions) {
set_insn_start(t, ureg_get_instruction_number(ureg));
- compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *) n, clamp_color);
+ compile_tgsi_instruction(t, inst, clamp_color);
}
/* Fix up all emitted labels:
@@ -5257,9 +5241,7 @@ get_mesa_program(struct gl_context *ctx,
do {
progress = GL_FALSE;
- foreach_list(node, &v->function_signatures) {
- function_entry *entry = (function_entry *) node;
-
+ foreach_in_list(function_entry, entry, &v->function_signatures) {
if (!entry->bgn_inst) {
v->current_function = entry;
@@ -5524,6 +5506,7 @@ st_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi,
so->output[i].num_components = info->Outputs[i].NumComponents;
so->output[i].output_buffer = info->Outputs[i].OutputBuffer;
so->output[i].dst_offset = info->Outputs[i].DstOffset;
+ so->output[i].stream = info->Outputs[i].StreamId;
}
for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index 1df411c3b..3570557fe 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -262,6 +262,10 @@ st_prepare_vertex_program(struct gl_context *ctx,
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_LAYER;
stvp->output_semantic_index[slot] = 0;
break;
+ case VARYING_SLOT_VIEWPORT:
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_VIEWPORT_INDEX;
+ stvp->output_semantic_index[slot] = 0;
+ break;
case VARYING_SLOT_TEX0:
case VARYING_SLOT_TEX1: