aboutsummaryrefslogtreecommitdiff
path: root/mesalib
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib')
-rw-r--r--mesalib/configure.ac22
-rw-r--r--mesalib/docs/relnotes/10.0.html1
-rw-r--r--mesalib/src/glsl/Makefile.sources1
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp18
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y3
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp2
-rwxr-xr-xmesalib/src/glsl/glsl_parser_extras.h2
-rw-r--r--mesalib/src/glsl/glsl_types.h2
-rw-r--r--mesalib/src/glsl/ir.h6
-rw-r--r--mesalib/src/glsl/ir_optimization.h1
-rw-r--r--mesalib/src/glsl/opt_cse.cpp599
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp1
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_sample_shading.xml19
-rw-r--r--mesalib/src/mapi/glapi/gen/GL4x.xml21
-rw-r--r--mesalib/src/mapi/glapi/gen/Makefile.am5
-rwxr-xr-xmesalib/src/mapi/glapi/gen/gl_API.xml4
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c28
-rw-r--r--mesalib/src/mesa/main/dd.h8
-rw-r--r--mesalib/src/mesa/main/enable.c18
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/get.c8
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py3
-rw-r--r--mesalib/src/mesa/main/mtypes.h19
-rw-r--r--mesalib/src/mesa/main/multisample.c18
-rw-r--r--mesalib/src/mesa/main/multisample.h2
-rw-r--r--mesalib/src/mesa/main/performance_monitor.c6
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c20
-rw-r--r--mesalib/src/mesa/main/transformfeedback.h3
-rw-r--r--mesalib/src/mesa/main/uniforms.c2
-rw-r--r--mesalib/src/mesa/main/vdpau.c6
-rw-r--r--mesalib/src/mesa/program/prog_print.c1
-rw-r--r--mesalib/src/mesa/program/prog_statevars.c11
-rw-r--r--mesalib/src/mesa/program/prog_statevars.h2
-rw-r--r--mesalib/src/mesa/program/program.c32
-rw-r--r--mesalib/src/mesa/program/program.h3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_xformfb.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.h2
-rw-r--r--mesalib/src/mesa/swrast/s_texfetch_tmp.h4
-rw-r--r--mesalib/src/mesa/vbo/vbo_attrib_tmp.h4
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c10
40 files changed, 867 insertions, 55 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index f94c9b979..0a250471e 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -1771,7 +1771,7 @@ if test "x$with_gallium_drivers" != x; then
PKG_CHECK_MODULES([RADEON], [libdrm_radeon >= $LIBDRM_RADEON_REQUIRED])
gallium_require_llvm "Gallium R300"
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
- gallium_check_st "radeon/drm" "r300/dri" "" "" "r300/xvmc" "r300/vdpau"
+ gallium_check_st "radeon/drm" "r300/dri" "" "" "" ""
DRICOMMON_NEED_LIBDRM=yes
;;
xr600)
@@ -1789,7 +1789,7 @@ if test "x$with_gallium_drivers" != x; then
if test "x$enable_opencl" = xyes; then
LLVM_COMPONENTS="${LLVM_COMPONENTS} bitreader asmparser"
fi
- gallium_check_st "radeon/drm" "r600/dri" "r600/xorg" "" "r600/xvmc" "r600/vdpau"
+ gallium_check_st "radeon/drm" "r600/dri" "" "" "r600/xvmc" "r600/vdpau"
DRICOMMON_NEED_LIBDRM=yes
;;
xradeonsi)
@@ -1798,7 +1798,7 @@ if test "x$with_gallium_drivers" != x; then
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi"
radeon_llvm_check
- gallium_check_st "radeon/drm" "radeonsi/dri" "radeonsi/xorg" "" "" "radeonsi/vdpau" ""
+ gallium_check_st "radeon/drm" "radeonsi/dri" "" "" "" "radeonsi/vdpau" ""
DRICOMMON_NEED_LIBDRM=yes
;;
xnouveau)
@@ -1828,16 +1828,6 @@ if test "x$with_gallium_drivers" != x; then
if test "x$enable_dri" = xyes; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast"
fi
- if test "x$enable_vdpau" = xyes; then
- GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS vdpau-softpipe"
- fi
- if test "x$enable_xvmc" = xyes; then
- GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS xvmc-softpipe"
- fi
- if test "x$enable_vdpau" = xyes -o "x$enable_xvmc" = xyes; then
- NEED_WINSYS_XLIB=yes
- GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib"
- fi
;;
*)
AC_MSG_ERROR([Unknown Gallium driver: $driver])
@@ -2044,23 +2034,17 @@ AC_CONFIG_FILES([Makefile
src/gallium/targets/pipe-loader/Makefile
src/gallium/targets/radeonsi/dri/Makefile
src/gallium/targets/radeonsi/vdpau/Makefile
- src/gallium/targets/radeonsi/xorg/Makefile
src/gallium/targets/r300/dri/Makefile
- src/gallium/targets/r300/vdpau/Makefile
- src/gallium/targets/r300/xvmc/Makefile
src/gallium/targets/r600/dri/Makefile
src/gallium/targets/r600/vdpau/Makefile
- src/gallium/targets/r600/xorg/Makefile
src/gallium/targets/r600/xvmc/Makefile
src/gallium/targets/libgl-xlib/Makefile
src/gallium/targets/vdpau-nouveau/Makefile
- src/gallium/targets/vdpau-softpipe/Makefile
src/gallium/targets/xa-vmwgfx/Makefile
src/gallium/targets/xa-vmwgfx/xatracker.pc
src/gallium/targets/xorg-i915/Makefile
src/gallium/targets/xorg-nouveau/Makefile
src/gallium/targets/xvmc-nouveau/Makefile
- src/gallium/targets/xvmc-softpipe/Makefile
src/gallium/tests/trivial/Makefile
src/gallium/tests/unit/Makefile
src/gallium/winsys/Makefile
diff --git a/mesalib/docs/relnotes/10.0.html b/mesalib/docs/relnotes/10.0.html
index ef550d154..5ff53398e 100644
--- a/mesalib/docs/relnotes/10.0.html
+++ b/mesalib/docs/relnotes/10.0.html
@@ -49,6 +49,7 @@ Note: some of the new features are only available with certain drivers.
<li>GL_ARB_texture_gather on i965.</li>
<li>GL_ARB_texture_query_levels on i965.</li>
<li>GL_ARB_texture_mirror_clamp_to_edge.</li>
+<li>GL_ARB_transform_feedback2, GL_ARB_transform_feedback3, and GL_ARB_transform_feedback_instanced on i965/Gen7 (with appropriate kernel support).</li>
<li>GL_KHR_debug</li>
</ul>
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index 2f7bfa163..2aabc0585 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/src/glsl/Makefile.sources
@@ -83,6 +83,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/opt_constant_variable.cpp \
$(GLSL_SRCDIR)/opt_copy_propagation.cpp \
$(GLSL_SRCDIR)/opt_copy_propagation_elements.cpp \
+ $(GLSL_SRCDIR)/opt_cse.cpp \
$(GLSL_SRCDIR)/opt_dead_builtin_varyings.cpp \
$(GLSL_SRCDIR)/opt_dead_code.cpp \
$(GLSL_SRCDIR)/opt_dead_code_local.cpp \
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index 7a3505ace..4d441045a 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -30,6 +30,9 @@
#include "program/prog_statevars.h"
#include "program/prog_instruction.h"
+static struct gl_builtin_uniform_element gl_NumSamples_elements[] = {
+ {NULL, {STATE_NUM_SAMPLES, 0, 0}, SWIZZLE_XXXX}
+};
static struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
{"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
@@ -236,6 +239,7 @@ static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
+ STATEVAR(gl_NumSamples),
STATEVAR(gl_DepthRange),
STATEVAR(gl_ClipPlane),
STATEVAR(gl_Point),
@@ -662,6 +666,7 @@ builtin_variable_generator::generate_constants()
void
builtin_variable_generator::generate_uniforms()
{
+ add_uniform(int_t, "gl_NumSamples");
add_uniform(type("gl_DepthRangeParameters"), "gl_DepthRange");
add_uniform(array(vec4_t, VERT_ATTRIB_MAX), "gl_CurrentAttribVertMESA");
add_uniform(array(vec4_t, VARYING_SLOT_MAX), "gl_CurrentAttribFragMESA");
@@ -838,6 +843,19 @@ builtin_variable_generator::generate_fs_special_vars()
if (state->AMD_shader_stencil_export_warn)
var->warn_extension = "GL_AMD_shader_stencil_export";
}
+
+ if (state->ARB_sample_shading_enable) {
+ add_system_value(SYSTEM_VALUE_SAMPLE_ID, int_t, "gl_SampleID");
+ add_system_value(SYSTEM_VALUE_SAMPLE_POS, vec2_t, "gl_SamplePosition");
+ /* From the ARB_sample_shading specification:
+ * "The number of elements in the array is ceil(<s>/32), where
+ * <s> is the maximum number of color samples supported by the
+ * implementation."
+ * Since no drivers expose more than 32x MSAA, we can simply set
+ * the array size to 1 rather than computing it.
+ */
+ add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), "gl_SampleMask");
+ }
}
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index 86f3cd5aa..7edc27488 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -1249,6 +1249,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
if (extensions->ARB_shading_language_420pack)
add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
+ if (extensions->ARB_sample_shading)
+ add_builtin_define(parser, "GL_ARB_sample_shading", 1);
+
if (extensions->EXT_shader_integer_mix)
add_builtin_define(parser, "GL_EXT_shader_integer_mix", 1);
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 77e8816c4..d922db9db 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -540,6 +540,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(EXT_shader_integer_mix, true, true, EXT_shader_integer_mix),
EXT(ARB_texture_gather, true, false, ARB_texture_gather),
EXT(ARB_shader_atomic_counters, true, false, ARB_shader_atomic_counters),
+ EXT(ARB_sample_shading, true, false, ARB_sample_shading),
};
#undef EXT
@@ -1604,6 +1605,7 @@ do_common_optimization(exec_list *ir, bool linked,
else
progress = do_constant_variable_unlinked(ir) || progress;
progress = do_constant_folding(ir) || progress;
+ progress = do_cse(ir) || progress;
progress = do_algebraic(ir) || progress;
progress = do_lower_jumps(ir) || progress;
progress = do_vec_index_to_swizzle(ir) || progress;
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 32f26c7f0..a30653eab 100755
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -354,6 +354,8 @@ struct _mesa_glsl_parse_state {
bool AMD_vertex_shader_layer_warn;
bool ARB_shading_language_420pack_enable;
bool ARB_shading_language_420pack_warn;
+ bool ARB_sample_shading_enable;
+ bool ARB_sample_shading_warn;
bool EXT_shader_integer_mix_enable;
bool EXT_shader_integer_mix_warn;
bool ARB_shader_atomic_counters_enable;
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index fdb1f3a6e..96eee5e64 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -459,7 +459,7 @@ struct glsl_type {
*/
bool contains_atomic() const
{
- return atomic_size();
+ return atomic_size() > 0;
}
/**
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index 5b30fe59b..2f06fb9ea 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -133,6 +133,7 @@ public:
virtual class ir_return * as_return() { return NULL; }
virtual class ir_if * as_if() { return NULL; }
virtual class ir_swizzle * as_swizzle() { return NULL; }
+ virtual class ir_texture * as_texture() { return NULL; }
virtual class ir_constant * as_constant() { return NULL; }
virtual class ir_discard * as_discard() { return NULL; }
virtual class ir_jump * as_jump() { return NULL; }
@@ -1731,6 +1732,11 @@ public:
v->visit(this);
}
+ virtual ir_texture *as_texture()
+ {
+ return this;
+ }
+
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
/**
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index 074686c5d..3ca9f5744 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -77,6 +77,7 @@ bool do_constant_variable_unlinked(exec_list *instructions);
bool do_copy_propagation(exec_list *instructions);
bool do_copy_propagation_elements(exec_list *instructions);
bool do_constant_propagation(exec_list *instructions);
+bool do_cse(exec_list *instructions);
void do_dead_builtin_varyings(struct gl_context *ctx,
gl_shader *producer, gl_shader *consumer,
unsigned num_tfeedback_decls,
diff --git a/mesalib/src/glsl/opt_cse.cpp b/mesalib/src/glsl/opt_cse.cpp
new file mode 100644
index 000000000..c0fdb23e6
--- /dev/null
+++ b/mesalib/src/glsl/opt_cse.cpp
@@ -0,0 +1,599 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file opt_cse.cpp
+ *
+ * constant subexpression elimination at the GLSL IR level.
+ *
+ * Compare to brw_fs_cse.cpp for a more complete CSE implementation. This one
+ * is generic and handles texture operations, but it's rather simple currently
+ * and doesn't support modification of variables in the available expressions
+ * list, so it can't do variables other than uniforms or shader inputs.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_rvalue_visitor.h"
+#include "ir_basic_block.h"
+#include "ir_optimization.h"
+#include "ir_builder.h"
+#include "glsl_types.h"
+
+using namespace ir_builder;
+
+static bool debug = false;
+
+namespace {
+
+/**
+ * This is the record of an available expression for common subexpression
+ * elimination.
+ */
+class ae_entry : public exec_node
+{
+public:
+ ae_entry(ir_instruction *base_ir, ir_rvalue **val)
+ : val(val), base_ir(base_ir)
+ {
+ assert(val);
+ assert(*val);
+ assert(base_ir);
+
+ var = NULL;
+ }
+
+ /**
+ * The pointer to the expression that we might be able to reuse
+ *
+ * Note the double pointer -- this is the place in the base_ir expression
+ * tree that we would rewrite to move the expression out to a new variable
+ * assignment.
+ */
+ ir_rvalue **val;
+
+ /**
+ * Root instruction in the basic block where the expression appeared.
+ *
+ * This is used so that we can insert the new variable declaration into the
+ * instruction stream (since *val is just somewhere in base_ir's expression
+ * tree).
+ */
+ ir_instruction *base_ir;
+
+ /**
+ * The variable that the expression has been stored in, if it's been CSEd
+ * once already.
+ */
+ ir_variable *var;
+};
+
+class cse_visitor : public ir_rvalue_visitor {
+public:
+ cse_visitor(exec_list *validate_instructions)
+ : validate_instructions(validate_instructions)
+ {
+ progress = false;
+ mem_ctx = ralloc_context(NULL);
+ this->ae = new(mem_ctx) exec_list;
+ }
+ ~cse_visitor()
+ {
+ ralloc_free(mem_ctx);
+ }
+
+ virtual ir_visitor_status visit_enter(ir_function_signature *ir);
+ virtual ir_visitor_status visit_enter(ir_loop *ir);
+ virtual ir_visitor_status visit_enter(ir_if *ir);
+ virtual ir_visitor_status visit_enter(ir_call *ir);
+ virtual void handle_rvalue(ir_rvalue **rvalue);
+
+ bool progress;
+
+private:
+ void *mem_ctx;
+
+ ir_rvalue *try_cse(ir_rvalue *rvalue);
+ void add_to_ae(ir_rvalue **rvalue);
+
+ /** List of ae_entry: The available expressions to reuse */
+ exec_list *ae;
+
+ /**
+ * The whole shader, so that we can validate_ir_tree in debug mode.
+ *
+ * This proved quite useful when trying to get the tree manipulation
+ * right.
+ */
+ exec_list *validate_instructions;
+};
+
+/**
+ * Visitor to walk an expression tree to check that all variables referenced
+ * are constants.
+ */
+class is_cse_candidate_visitor : public ir_hierarchical_visitor
+{
+public:
+
+ is_cse_candidate_visitor()
+ : ok(true)
+ {
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir);
+
+ bool ok;
+};
+
+
+class contains_rvalue_visitor : public ir_rvalue_visitor
+{
+public:
+
+ contains_rvalue_visitor(ir_rvalue *val)
+ : val(val)
+ {
+ found = false;
+ }
+
+ virtual void handle_rvalue(ir_rvalue **rvalue);
+
+ bool found;
+
+private:
+ ir_rvalue *val;
+};
+
+} /* unnamed namespace */
+
+static void
+dump_ae(exec_list *ae)
+{
+ int i = 0;
+
+ printf("CSE: AE contents:\n");
+ foreach_list(node, ae) {
+ ae_entry *entry = (ae_entry *)node;
+
+ printf("CSE: AE %2d (%p): ", i, entry);
+ (*entry->val)->print();
+ printf("\n");
+
+ if (entry->var)
+ printf("CSE: in var %p:\n", entry->var);
+
+ i++;
+ }
+}
+
+ir_visitor_status
+is_cse_candidate_visitor::visit(ir_dereference_variable *ir)
+{
+ /* Currently, since we don't handle kills of the ae based on variables
+ * getting assigned, we can only handle constant variables.
+ */
+ if (ir->var->read_only) {
+ return visit_continue;
+ } else {
+ ok = false;
+ return visit_stop;
+ }
+}
+
+void
+contains_rvalue_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (*rvalue == val)
+ found = true;
+}
+
+static bool
+contains_rvalue(ir_rvalue *haystack, ir_rvalue *needle)
+{
+ contains_rvalue_visitor v(needle);
+ haystack->accept(&v);
+ return v.found;
+}
+
+static bool
+is_cse_candidate(ir_rvalue *ir)
+{
+ /* Our temporary variable assignment generation isn't ready to handle
+ * anything bigger than a vector.
+ */
+ if (!ir->type->is_vector() && !ir->type->is_scalar())
+ return false;
+
+ /* Only handle expressions and textures currently. We may want to extend
+ * to variable-index array dereferences at some point.
+ */
+ switch (ir->ir_type) {
+ case ir_type_expression:
+ case ir_type_texture:
+ break;
+ default:
+ return false;
+ }
+
+ is_cse_candidate_visitor v;
+
+ ir->accept(&v);
+
+ return v.ok;
+}
+
+static bool
+equals(ir_rvalue *a, ir_rvalue *b);
+
+static bool
+equals(ir_constant *a, ir_constant *b)
+{
+ if (!a || !b)
+ return false;
+
+ if (a->type != b->type)
+ return false;
+
+ for (unsigned i = 0; i < a->type->components(); i++) {
+ if (a->value.u[i] != b->value.u[i])
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+equals(ir_dereference_variable *a, ir_dereference_variable *b)
+{
+ if (!a || !b)
+ return false;
+
+ return a->var == b->var;
+}
+
+static bool
+equals(ir_dereference_array *a, ir_dereference_array *b)
+{
+ if (!a || !b)
+ return false;
+
+ if (!equals(a->array, b->array))
+ return false;
+
+ if (!equals(a->array_index, b->array_index))
+ return false;
+
+ return true;
+}
+
+static bool
+equals(ir_swizzle *a, ir_swizzle *b)
+{
+ if (!a || !b)
+ return false;
+
+ if (a->type != b->type)
+ return false;
+
+ if (a->mask.x != b->mask.x ||
+ a->mask.y != b->mask.y ||
+ a->mask.z != b->mask.z ||
+ a->mask.w != b->mask.w) {
+ return false;
+ }
+
+ return equals(a->val, b->val);
+}
+
+static bool
+equals(ir_texture *a, ir_texture *b)
+{
+ if (!a || !b)
+ return false;
+
+ if (a->type != b->type)
+ return false;
+
+ if (a->op != b->op)
+ return false;
+
+ if (!equals(a->coordinate, b->coordinate))
+ return false;
+
+ if (!equals(a->projector, b->projector))
+ return false;
+
+ if (!equals(a->shadow_comparitor, b->shadow_comparitor))
+ return false;
+
+ if (!equals(a->offset, b->offset))
+ return false;
+
+ if (!equals(a->sampler, b->sampler))
+ return false;
+
+ switch (a->op) {
+ case ir_tex:
+ case ir_lod:
+ case ir_query_levels:
+ break;
+ case ir_txb:
+ if (!equals(a->lod_info.bias, b->lod_info.bias))
+ return false;
+ break;
+ case ir_txl:
+ case ir_txf:
+ case ir_txs:
+ if (!equals(a->lod_info.lod, b->lod_info.lod))
+ return false;
+ break;
+ case ir_txd:
+ if (!equals(a->lod_info.grad.dPdx, b->lod_info.grad.dPdx) ||
+ !equals(a->lod_info.grad.dPdy, b->lod_info.grad.dPdy))
+ return false;
+ case ir_txf_ms:
+ if (!equals(a->lod_info.sample_index, b->lod_info.sample_index))
+ return false;
+ break;
+ case ir_tg4:
+ if (!equals(a->lod_info.component, b->lod_info.component))
+ return false;
+ default:
+ assert(!"Unrecognized texture op");
+ }
+
+ return true;
+}
+
+static bool
+equals(ir_expression *a, ir_expression *b)
+{
+ if (!a || !b)
+ return false;
+
+ if (a->type != b->type)
+ return false;
+
+ if (a->operation != b->operation)
+ return false;
+
+ for (unsigned i = 0; i < a->get_num_operands(); i++) {
+ if (!equals(a->operands[i], b->operands[i]))
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+equals(ir_rvalue *a, ir_rvalue *b)
+{
+ if (!a || !b)
+ return !a && !b;
+
+ if (a->type != b->type)
+ return false;
+
+ switch (a->ir_type) {
+ case ir_type_texture:
+ return equals(a->as_texture(), b->as_texture());
+
+ case ir_type_constant:
+ return equals(a->as_constant(), b->as_constant());
+
+ case ir_type_expression:
+ return equals(a->as_expression(), b->as_expression());
+
+ case ir_type_dereference_variable:
+ return equals(a->as_dereference_variable(), b->as_dereference_variable());
+
+ case ir_type_dereference_array:
+ return equals(a->as_dereference_array(), b->as_dereference_array());
+
+ case ir_type_swizzle:
+ return equals(a->as_swizzle(), b->as_swizzle());
+
+ default:
+ return false;
+ }
+}
+
+/**
+ * Tries to find and return a reference to a previous computation of a given
+ * expression.
+ *
+ * Walk the list of available expressions checking if any of them match the
+ * rvalue, and if so, move the previous copy of the expression to a temporary
+ * and return a reference of the temporary.
+ */
+ir_rvalue *
+cse_visitor::try_cse(ir_rvalue *rvalue)
+{
+ foreach_list(node, ae) {
+ ae_entry *entry = (ae_entry *)node;
+
+ if (debug) {
+ printf("Comparing to AE %p: ", entry);
+ (*entry->val)->print();
+ printf("\n");
+ }
+
+ if (!equals(rvalue, *entry->val))
+ continue;
+
+ if (debug) {
+ printf("CSE: Replacing: ");
+ (*entry->val)->print();
+ printf("\n");
+ printf("CSE: with: ");
+ rvalue->print();
+ printf("\n");
+ }
+
+ if (!entry->var) {
+ ir_instruction *base_ir = entry->base_ir;
+
+ ir_variable *var = new(rvalue) ir_variable(rvalue->type,
+ "cse",
+ ir_var_auto);
+
+ /* Write the previous expression result into a new variable. */
+ base_ir->insert_before(var);
+ ir_assignment *assignment = assign(var, *entry->val);
+ base_ir->insert_before(assignment);
+
+ /* Replace the expression in the original tree with a deref of the
+ * variable, but keep tracking the expression for further reuse.
+ */
+ *entry->val = new(rvalue) ir_dereference_variable(var);
+ entry->val = &assignment->rhs;
+
+ entry->var = var;
+
+ /* Update the base_irs in the AE list. We have to be sure that
+ * they're correct -- expressions from our base_ir that weren't moved
+ * need to stay in this base_ir (so that later consumption of them
+ * puts new variables between our new variable and our base_ir), but
+ * expressions from our base_ir that we *did* move need base_ir
+ * 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;
+ if (contains_rvalue(assignment->rhs, *fixup_entry->val))
+ fixup_entry->base_ir = assignment;
+ }
+
+ if (debug)
+ dump_ae(ae);
+ }
+
+ /* Replace the expression in our current tree with the variable. */
+ return new(rvalue) ir_dereference_variable(entry->var);
+ }
+
+ return NULL;
+}
+
+/** Add the rvalue to the list of available expressions for CSE. */
+void
+cse_visitor::add_to_ae(ir_rvalue **rvalue)
+{
+ if (debug) {
+ printf("CSE: Add to AE: ");
+ (*rvalue)->print();
+ printf("\n");
+ }
+
+ ae->push_tail(new(mem_ctx) ae_entry(base_ir, rvalue));
+
+ if (debug)
+ dump_ae(ae);
+}
+
+void
+cse_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ if (debug) {
+ printf("CSE: handle_rvalue ");
+ (*rvalue)->print();
+ printf("\n");
+ }
+
+ if (!is_cse_candidate(*rvalue))
+ return;
+
+ ir_rvalue *new_rvalue = try_cse(*rvalue);
+ if (new_rvalue) {
+ *rvalue = new_rvalue;
+ progress = true;
+
+ if (debug)
+ validate_ir_tree(validate_instructions);
+ } else {
+ add_to_ae(rvalue);
+ }
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_if *ir)
+{
+ handle_rvalue(&ir->condition);
+
+ ae->make_empty();
+ visit_list_elements(this, &ir->then_instructions);
+
+ ae->make_empty();
+ visit_list_elements(this, &ir->else_instructions);
+
+ ae->make_empty();
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_function_signature *ir)
+{
+ ae->make_empty();
+ visit_list_elements(this, &ir->body);
+
+ ae->make_empty();
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_loop *ir)
+{
+ ae->make_empty();
+ visit_list_elements(this, &ir->body_instructions);
+
+ ae->make_empty();
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_call *ir)
+{
+ /* Because call is an exec_list of ir_rvalues, handle_rvalue gets passed a
+ * pointer to the (ir_rvalue *) on the stack. Since we save those pointers
+ * in the AE list, we can't let handle_rvalue get called.
+ */
+ return visit_continue_with_parent;
+}
+
+/**
+ * Does a (uniform-value) constant subexpression elimination pass on the code
+ * present in the instruction stream.
+ */
+bool
+do_cse(exec_list *instructions)
+{
+ cse_visitor v(instructions);
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp
index 7a1cf6877..cbff6d182 100644
--- a/mesalib/src/glsl/standalone_scaffolding.cpp
+++ b/mesalib/src/glsl/standalone_scaffolding.cpp
@@ -97,6 +97,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
ctx->Extensions.ARB_explicit_attrib_location = true;
ctx->Extensions.ARB_fragment_coord_conventions = true;
ctx->Extensions.ARB_gpu_shader5 = true;
+ ctx->Extensions.ARB_sample_shading = true;
ctx->Extensions.ARB_shader_bit_encoding = true;
ctx->Extensions.ARB_shader_stencil_export = true;
ctx->Extensions.ARB_shader_texture_lod = true;
diff --git a/mesalib/src/mapi/glapi/gen/ARB_sample_shading.xml b/mesalib/src/mapi/glapi/gen/ARB_sample_shading.xml
new file mode 100644
index 000000000..cc8296a47
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_sample_shading.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+<OpenGLAPI>
+
+<category name="GL_ARB_sample_shading" number="70">
+
+ <enum name="SAMPLE_SHADING_ARB" value="0x8C36"/>
+ <enum name="MIN_SAMPLE_SHADING_VALUE_ARB" value="0x8C37"/>
+
+ <function name="MinSampleShadingARB" alias="MinSampleShading">
+ <param name="value" type="GLfloat"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/GL4x.xml b/mesalib/src/mapi/glapi/gen/GL4x.xml
new file mode 100644
index 000000000..6706278ce
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/GL4x.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+<OpenGLAPI>
+
+<category name="4.0">
+ <enum name="SAMPLE_SHADING" value="0x8C36"/>
+ <enum name="MIN_SAMPLE_SHADING_VALUE" value="0x8C37"/>
+
+ <function name="MinSampleShading" offset="assign">
+ <param name="value" type="GLfloat"/>
+ </function>
+</category>
+
+<category name="4.3">
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am
index 390245216..cbbf659dd 100644
--- a/mesalib/src/mapi/glapi/gen/Makefile.am
+++ b/mesalib/src/mapi/glapi/gen/Makefile.am
@@ -108,6 +108,7 @@ API_XML = \
ARB_invalidate_subdata.xml \
ARB_map_buffer_range.xml \
ARB_robustness.xml \
+ ARB_sample_shading.xml \
ARB_sampler_objects.xml \
ARB_seamless_cube_map.xml \
ARB_shader_atomic_counters.xml \
@@ -144,7 +145,9 @@ API_XML = \
NV_texture_barrier.xml \
NV_vdpau_interop.xml \
OES_EGL_image.xml \
- GL3x.xml
+ GL3x.xml \
+ GL4x.xml
+
COMMON = $(API_XML) \
diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml
index eb42258fa..97d67244c 100755
--- a/mesalib/src/mapi/glapi/gen/gl_API.xml
+++ b/mesalib/src/mapi/glapi/gen/gl_API.xml
@@ -8187,7 +8187,7 @@
<xi:include href="ARB_draw_buffers_blend.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="AMD_draw_buffers_blend.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
-<!-- 70. GL_ARB_sample_shading -->
+<xi:include href="ARB_sample_shading.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="ARB_texture_cube_map_array.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="ARB_texture_gather.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- 73. GL_ARB_texture_query_lod -->
@@ -13122,4 +13122,6 @@
<xi:include href="NV_vdpau_interop.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<xi:include href="GL4x.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
</OpenGLAPI>
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index 798efa680..aa50dde73 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -1729,10 +1729,10 @@ blitframebuffer_texture(struct gl_context *ctx,
}
else {
assert(target == GL_TEXTURE_RECTANGLE_ARB);
- s0 = srcX0;
- s1 = srcX1;
- t0 = srcY0;
- t1 = srcY1;
+ s0 = (float) srcX0;
+ s1 = (float) srcX1;
+ t0 = (float) srcY0;
+ t1 = (float) srcY1;
}
/* setup vertex positions */
@@ -2825,7 +2825,7 @@ _mesa_meta_DrawPixels(struct gl_context *ctx,
_mesa_StencilMask(mask);
_mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
- 255.0 / mask, 0.5, 0.0, 0.0);
+ 255.0f / mask, 0.5f, 0.0f, 0.0f);
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
@@ -3184,7 +3184,7 @@ setup_texture_coords(GLenum faceTarget,
r = (slice + 0.5f) / depth;
}
else if (faceTarget == GL_TEXTURE_2D_ARRAY)
- r = slice;
+ r = (float) slice;
else
r = 0.0F;
coords0[0] = 0.0F; /* s */
@@ -3204,28 +3204,28 @@ setup_texture_coords(GLenum faceTarget,
coords0[0] = 0.0F; /* s */
coords0[1] = 0.0F; /* t */
coords0[2] = 0.0F; /* r */
- coords1[0] = width;
+ coords1[0] = (float) width;
coords1[1] = 0.0F;
coords1[2] = 0.0F;
- coords2[0] = width;
- coords2[1] = height;
+ coords2[0] = (float) width;
+ coords2[1] = (float) height;
coords2[2] = 0.0F;
coords3[0] = 0.0F;
- coords3[1] = height;
+ coords3[1] = (float) height;
coords3[2] = 0.0F;
break;
case GL_TEXTURE_1D_ARRAY:
coords0[0] = 0.0F; /* s */
- coords0[1] = slice; /* t */
+ coords0[1] = (float) slice; /* t */
coords0[2] = 0.0F; /* r */
coords1[0] = 1.0f;
- coords1[1] = slice;
+ coords1[1] = (float) slice;
coords1[2] = 0.0F;
coords2[0] = 1.0F;
- coords2[1] = slice;
+ coords2[1] = (float) slice;
coords2[2] = 0.0F;
coords3[0] = 0.0F;
- coords3[1] = slice;
+ coords3[1] = (float) slice;
coords3[2] = 0.0F;
break;
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index 501192199..d7c432713 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -843,6 +843,14 @@ struct dd_function_table {
struct gl_transform_feedback_object *obj);
/**
+ * Return the number of vertices written to a stream during the last
+ * Begin/EndTransformFeedback block.
+ */
+ GLsizei (*GetTransformFeedbackVertexCount)(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj,
+ GLuint stream);
+
+ /**
* \name GL_NV_texture_barrier interface
*/
void (*TextureBarrier)(struct gl_context *ctx);
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index 5e2fd80d2..dd6a772f9 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -802,6 +802,17 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
ctx->Multisample.SampleCoverageInvert = state;
break;
+ /* GL_ARB_sample_shading */
+ case GL_SAMPLE_SHADING:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum_error;
+ CHECK_EXTENSION(ARB_sample_shading, cap);
+ if (ctx->Multisample.SampleShading == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleShading = state;
+ break;
+
/* GL_IBM_rasterpos_clip */
case GL_RASTER_POSITION_UNCLIPPED_IBM:
if (ctx->API != API_OPENGL_COMPAT)
@@ -1594,6 +1605,13 @@ _mesa_IsEnabled( GLenum cap )
CHECK_EXTENSION(ARB_texture_multisample);
return ctx->Multisample.SampleMask;
+ /* ARB_sample_shading */
+ case GL_SAMPLE_SHADING:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum_error;
+ CHECK_EXTENSION(ARB_sample_shading);
+ return ctx->Multisample.SampleShading;
+
default:
goto invalid_enum_error;
}
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 285ec377c..48c4e9f1b 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -118,6 +118,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_point_sprite", o(ARB_point_sprite), GL, 2003 },
{ "GL_ARB_provoking_vertex", o(EXT_provoking_vertex), GL, 2009 },
{ "GL_ARB_robustness", o(dummy_true), GL, 2010 },
+ { "GL_ARB_sample_shading", o(ARB_sample_shading), GL, 2009 },
{ "GL_ARB_sampler_objects", o(dummy_true), GL, 2009 },
{ "GL_ARB_seamless_cube_map", o(ARB_seamless_cube_map), GL, 2009 },
{ "GL_ARB_shader_atomic_counters", o(ARB_shader_atomic_counters), GL, 2011 },
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 6e72ff5c2..6a0de0c16 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -131,6 +131,7 @@ enum value_extra {
EXTRA_VERSION_30,
EXTRA_VERSION_31,
EXTRA_VERSION_32,
+ EXTRA_VERSION_40,
EXTRA_API_GL,
EXTRA_API_GL_CORE,
EXTRA_API_ES2,
@@ -391,6 +392,7 @@ extra_NV_primitive_restart[] = {
static const int extra_version_30[] = { EXTRA_VERSION_30, EXTRA_END };
static const int extra_version_31[] = { EXTRA_VERSION_31, EXTRA_END };
static const int extra_version_32[] = { EXTRA_VERSION_32, EXTRA_END };
+static const int extra_version_40[] = { EXTRA_VERSION_40, EXTRA_END };
static const int extra_gl30_es3[] = {
EXTRA_VERSION_30,
@@ -410,6 +412,12 @@ static const int extra_gl32_ARB_geometry_shader4[] = {
EXTRA_END
};
+static const int extra_gl40_ARB_sample_shading[] = {
+ EXTRA_VERSION_40,
+ EXT(ARB_sample_shading),
+ EXTRA_END
+};
+
static const int
extra_ARB_vertex_program_api_es2[] = {
EXT(ARB_vertex_program),
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index 9f79f3406..0851b7b70 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -83,6 +83,9 @@ descriptor=[
[ "SAMPLE_BUFFERS_ARB", "BUFFER_INT(Visual.sampleBuffers), extra_new_buffers" ],
[ "SAMPLES_ARB", "BUFFER_INT(Visual.samples), extra_new_buffers" ],
+# GL_ARB_sample_shading
+ [ "MIN_SAMPLE_SHADING_VALUE_ARB", "CONTEXT_FLOAT(Multisample.MinSampleShadingValue), extra_gl40_ARB_sample_shading" ],
+
# GL_SGIS_generate_mipmap
[ "GENERATE_MIPMAP_HINT_SGIS", "CONTEXT_ENUM(Hint.GenerateMipmap), NO_EXTRA" ],
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index a1a5eb4bf..b5c5583d6 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -274,6 +274,11 @@ typedef enum
#define VARYING_BIT_VAR(V) BITFIELD64_BIT(VARYING_SLOT_VAR0 + (V))
/*@}*/
+/**
+ * Bitflags for system values.
+ */
+#define SYSTEM_BIT_SAMPLE_ID BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_ID)
+#define SYSTEM_BIT_SAMPLE_POS BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_POS)
/**
* Determine if the given gl_varying_slot appears in the fragment shader.
@@ -306,12 +311,13 @@ typedef enum
* register is written. No FRAG_RESULT_DATAn will be written.
*/
FRAG_RESULT_COLOR = 2,
+ FRAG_RESULT_SAMPLE_MASK = 3,
/* FRAG_RESULT_DATAn are the per-render-target (GLSL gl_FragData[n]
* or ARB_fragment_program fragment.color[n]) color results. If
* any are written, FRAG_RESULT_COLOR will not be written.
*/
- FRAG_RESULT_DATA0 = 3,
+ FRAG_RESULT_DATA0 = 4,
FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
} gl_frag_result;
@@ -872,6 +878,8 @@ struct gl_multisample_attrib
GLboolean SampleCoverage;
GLfloat SampleCoverageValue;
GLboolean SampleCoverageInvert;
+ GLboolean SampleShading;
+ GLfloat MinSampleShadingValue;
/* ARB_texture_multisample / GL3.2 additions */
GLboolean SampleMask;
@@ -1902,6 +1910,8 @@ typedef enum
SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */
SYSTEM_VALUE_VERTEX_ID, /**< Vertex shader only */
SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */
+ SYSTEM_VALUE_SAMPLE_ID, /**< Fragment shader only */
+ SYSTEM_VALUE_SAMPLE_POS, /**< Fragment shader only */
SYSTEM_VALUE_MAX /**< Number of values */
} gl_system_value;
@@ -3156,6 +3166,12 @@ struct gl_constants
*/
GLboolean PrimitiveRestartInSoftware;
+ /**
+ * Always use the GetTransformFeedbackVertexCount() driver hook, rather
+ * than passing the transform feedback object to the drawing function.
+ */
+ GLboolean AlwaysUseGetTransformFeedbackVertexCount;
+
/** GL_ARB_map_buffer_alignment */
GLuint MinMapBufferAlignment;
@@ -3239,6 +3255,7 @@ struct gl_extensions
GLboolean ARB_occlusion_query;
GLboolean ARB_occlusion_query2;
GLboolean ARB_point_sprite;
+ GLboolean ARB_sample_shading;
GLboolean ARB_seamless_cube_map;
GLboolean ARB_shader_atomic_counters;
GLboolean ARB_shader_bit_encoding;
diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c
index bd97c5096..599cdee74 100644
--- a/mesalib/src/mesa/main/multisample.c
+++ b/mesalib/src/mesa/main/multisample.c
@@ -119,6 +119,24 @@ _mesa_SampleMaski(GLuint index, GLbitfield mask)
ctx->Multisample.SampleMaskValue = mask;
}
+/**
+ * Called via glMinSampleShadingARB
+ */
+void GLAPIENTRY
+_mesa_MinSampleShading(GLclampf value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.ARB_sample_shading || !_mesa_is_desktop_gl(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glMinSampleShading");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, 0);
+
+ ctx->Multisample.MinSampleShadingValue = CLAMP(value, 0.0, 1.0);
+ ctx->NewState |= _NEW_MULTISAMPLE;
+}
/**
* Helper for checking a requested sample count against the limit
diff --git a/mesalib/src/mesa/main/multisample.h b/mesalib/src/mesa/main/multisample.h
index 66848d269..7441d3ee9 100644
--- a/mesalib/src/mesa/main/multisample.h
+++ b/mesalib/src/mesa/main/multisample.h
@@ -44,6 +44,8 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
extern void GLAPIENTRY
_mesa_SampleMaski(GLuint index, GLbitfield mask);
+extern void GLAPIENTRY
+_mesa_MinSampleShading(GLclampf value);
extern GLenum
_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c
index 8dfa8261e..17cae5183 100644
--- a/mesalib/src/mesa/main/performance_monitor.c
+++ b/mesalib/src/mesa/main/performance_monitor.c
@@ -127,7 +127,7 @@ _mesa_GetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize,
if (groupsSize > 0 && groups != NULL) {
unsigned i;
- unsigned n = MIN2(groupsSize, ctx->PerfMonitor.NumGroups);
+ unsigned n = MIN2((GLuint) groupsSize, ctx->PerfMonitor.NumGroups);
/* We just use the index in the Groups array as the ID. */
for (i = 0; i < n; i++)
@@ -156,7 +156,7 @@ _mesa_GetPerfMonitorCountersAMD(GLuint group, GLint *numCounters,
if (counters != NULL) {
unsigned i;
- unsigned n = MIN2(group_obj->NumCounters, countersSize);
+ unsigned n = MIN2(group_obj->NumCounters, (GLuint) countersSize);
for (i = 0; i < n; i++) {
/* We just use the index in the Counters array as the ID. */
counters[i] = i;
@@ -379,7 +379,7 @@ _mesa_SelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable,
GLuint *counterList)
{
GET_CURRENT_CONTEXT(ctx);
- unsigned i;
+ int i;
struct gl_perf_monitor_object *m;
const struct gl_perf_monitor_group *group_obj;
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index bc9b52ab9..76d213b16 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -205,17 +205,27 @@ _mesa_free_transform_feedback(struct gl_context *ctx)
}
+/** Initialize the fields of a gl_transform_feedback_object. */
+void
+_mesa_init_transform_feedback_object(struct gl_transform_feedback_object *obj,
+ GLuint name)
+{
+ if (!obj)
+ return;
+
+ obj->Name = name;
+ obj->RefCount = 1;
+ obj->EverBound = GL_FALSE;
+}
+
+
/** Default fallback for ctx->Driver.NewTransformFeedback() */
static struct gl_transform_feedback_object *
new_transform_feedback(struct gl_context *ctx, GLuint name)
{
struct gl_transform_feedback_object *obj;
obj = CALLOC_STRUCT(gl_transform_feedback_object);
- if (obj) {
- obj->Name = name;
- obj->RefCount = 1;
- obj->EverBound = GL_FALSE;
- }
+ _mesa_init_transform_feedback_object(obj, name);
return obj;
}
diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h
index 0ffaab508..7aecd66a7 100644
--- a/mesalib/src/mesa/main/transformfeedback.h
+++ b/mesalib/src/mesa/main/transformfeedback.h
@@ -91,6 +91,9 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
/*** GL_ARB_transform_feedback2 ***/
+extern void
+_mesa_init_transform_feedback_object(struct gl_transform_feedback_object *obj,
+ GLuint name);
struct gl_transform_feedback_object *
_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name);
diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c
index 2e847fe31..17e24f678 100644
--- a/mesalib/src/mesa/main/uniforms.c
+++ b/mesalib/src/mesa/main/uniforms.c
@@ -853,7 +853,7 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg;
struct gl_active_atomic_buffer *ab;
- int i;
+ GLuint i;
if (!ctx->Extensions.ARB_shader_atomic_counters) {
_mesa_error(ctx, GL_INVALID_OPERATION,
diff --git a/mesalib/src/mesa/main/vdpau.c b/mesalib/src/mesa/main/vdpau.c
index e21a26b43..359757607 100644
--- a/mesalib/src/mesa/main/vdpau.c
+++ b/mesalib/src/mesa/main/vdpau.c
@@ -324,7 +324,7 @@ void GLAPIENTRY
_mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
{
GET_CURRENT_CONTEXT(ctx);
- int i, j;
+ int i;
if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
_mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV");
@@ -348,6 +348,7 @@ _mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
for (i = 0; i < numSurfaces; ++i) {
struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
unsigned numTextureNames = surf->output ? 1 : 4;
+ unsigned j;
for (j = 0; j < numTextureNames; ++j) {
struct gl_texture_object *tex = surf->textures[j];
@@ -377,7 +378,7 @@ void GLAPIENTRY
_mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
{
GET_CURRENT_CONTEXT(ctx);
- int i, j;
+ int i;
if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
_mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV");
@@ -401,6 +402,7 @@ _mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
for (i = 0; i < numSurfaces; ++i) {
struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
unsigned numTextureNames = surf->output ? 1 : 4;
+ unsigned j;
for (j = 0; j < numTextureNames; ++j) {
struct gl_texture_object *tex = surf->textures[j];
diff --git a/mesalib/src/mesa/program/prog_print.c b/mesalib/src/mesa/program/prog_print.c
index cf852132d..fa9063f5b 100644
--- a/mesalib/src/mesa/program/prog_print.c
+++ b/mesalib/src/mesa/program/prog_print.c
@@ -311,6 +311,7 @@ arb_output_attrib_string(GLint index, GLenum progType)
"result.depth", /* FRAG_RESULT_DEPTH */
"result.(one)", /* FRAG_RESULT_STENCIL */
"result.color", /* FRAG_RESULT_COLOR */
+ "result.samplemask", /* FRAG_RESULT_SAMPLE_MASK */
"result.color[0]", /* FRAG_RESULT_DATA0 (named for GLSL's gl_FragData) */
"result.color[1]",
"result.color[2]",
diff --git a/mesalib/src/mesa/program/prog_statevars.c b/mesalib/src/mesa/program/prog_statevars.c
index 145c07c67..f6fd53576 100644
--- a/mesalib/src/mesa/program/prog_statevars.c
+++ b/mesalib/src/mesa/program/prog_statevars.c
@@ -349,6 +349,9 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
}
}
return;
+ case STATE_NUM_SAMPLES:
+ ((int *)value)[0] = ctx->DrawBuffer->Visual.samples;
+ return;
case STATE_DEPTH_RANGE:
value[0] = ctx->Viewport.Near; /* near */
value[1] = ctx->Viewport.Far; /* far */
@@ -665,6 +668,9 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
case STATE_PROGRAM_MATRIX:
return _NEW_TRACK_MATRIX;
+ case STATE_NUM_SAMPLES:
+ return _NEW_BUFFERS;
+
case STATE_DEPTH_RANGE:
return _NEW_VIEWPORT;
@@ -852,6 +858,9 @@ append_token(char *dst, gl_state_index k)
case STATE_TEXENV_COLOR:
append(dst, "texenv");
break;
+ case STATE_NUM_SAMPLES:
+ append(dst, "numsamples");
+ break;
case STATE_DEPTH_RANGE:
append(dst, "depth.range");
break;
@@ -1027,6 +1036,8 @@ _mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
break;
case STATE_FOG_COLOR:
break;
+ case STATE_NUM_SAMPLES:
+ break;
case STATE_DEPTH_RANGE:
break;
case STATE_FRAGMENT_PROGRAM:
diff --git a/mesalib/src/mesa/program/prog_statevars.h b/mesalib/src/mesa/program/prog_statevars.h
index ec22b7376..23a9f48c3 100644
--- a/mesalib/src/mesa/program/prog_statevars.h
+++ b/mesalib/src/mesa/program/prog_statevars.h
@@ -103,6 +103,8 @@ typedef enum gl_state_index_ {
STATE_TEXENV_COLOR,
+ STATE_NUM_SAMPLES, /* An integer, not a float like the other state vars */
+
STATE_DEPTH_RANGE,
STATE_VERTEX_PROGRAM,
diff --git a/mesalib/src/mesa/program/program.c b/mesalib/src/mesa/program/program.c
index 093d37297..a102ec17a 100644
--- a/mesalib/src/mesa/program/program.c
+++ b/mesalib/src/mesa/program/program.c
@@ -32,6 +32,7 @@
#include "main/glheader.h"
#include "main/context.h"
#include "main/hash.h"
+#include "main/macros.h"
#include "program.h"
#include "prog_cache.h"
#include "prog_parameter.h"
@@ -1024,3 +1025,34 @@ _mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog)
}
}
+
+/* Gets the minimum number of shader invocations per fragment.
+ * This function is useful to determine if we need to do per
+ * sample shading or per fragment shading.
+ */
+GLint
+_mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
+ const struct gl_fragment_program *prog)
+{
+ /* From ARB_sample_shading specification:
+ * "Using gl_SampleID in a fragment shader causes the entire shader
+ * to be evaluated per-sample."
+ *
+ * "Using gl_SamplePosition in a fragment shader causes the entire
+ * shader to be evaluated per-sample."
+ *
+ * "If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading
+ * has no effect."
+ */
+ if (ctx->Multisample.Enabled) {
+ if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
+ SYSTEM_BIT_SAMPLE_POS))
+ return MAX2(ctx->DrawBuffer->Visual.samples, 1);
+ else if (ctx->Multisample.SampleShading)
+ return MAX2(ceil(ctx->Multisample.MinSampleShadingValue *
+ ctx->DrawBuffer->Visual.samples), 1);
+ else
+ return 1;
+ }
+ return 1;
+}
diff --git a/mesalib/src/mesa/program/program.h b/mesalib/src/mesa/program/program.h
index 34965ab99..353ccab47 100644
--- a/mesalib/src/mesa/program/program.h
+++ b/mesalib/src/mesa/program/program.h
@@ -187,6 +187,9 @@ _mesa_valid_register_index(const struct gl_context *ctx,
extern void
_mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog);
+extern GLint
+_mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
+ const struct gl_fragment_program *prog);
static inline GLuint
_mesa_program_target_to_index(GLenum v)
diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
index e1a7a88a1..e824fe9b3 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
@@ -74,8 +74,8 @@ st_new_transform_feedback(struct gl_context *ctx, GLuint name)
if (!obj)
return NULL;
- obj->base.Name = name;
- obj->base.RefCount = 1;
+ _mesa_init_transform_feedback_object(&obj->base, name);
+
return &obj->base;
}
diff --git a/mesalib/src/mesa/state_tracker/st_draw.h b/mesalib/src/mesa/state_tracker/st_draw.h
index 3313fc8c7..394473b20 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.h
+++ b/mesalib/src/mesa/state_tracker/st_draw.h
@@ -77,7 +77,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
static INLINE unsigned
pointer_to_offset(const void *ptr)
{
- return (unsigned) (((unsigned long) ptr) & 0xffffffffUL);
+ return (unsigned) (((GLsizeiptr) ptr) & 0xffffffffUL);
}
diff --git a/mesalib/src/mesa/swrast/s_texfetch_tmp.h b/mesalib/src/mesa/swrast/s_texfetch_tmp.h
index 7a687532d..e2521b50c 100644
--- a/mesalib/src/mesa/swrast/s_texfetch_tmp.h
+++ b/mesalib/src/mesa/swrast/s_texfetch_tmp.h
@@ -1537,7 +1537,7 @@ static void FETCH(f_z24_s8)( const struct swrast_texture_image *texImage,
/* only return Z, not stencil data */
const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
- texel[0] = ((*src) >> 8) * scale;
+ texel[0] = (GLfloat) (((*src) >> 8) * scale);
ASSERT(texImage->Base.TexFormat == MESA_FORMAT_Z24_S8 ||
texImage->Base.TexFormat == MESA_FORMAT_Z24_X8);
ASSERT(texel[0] >= 0.0F);
@@ -1555,7 +1555,7 @@ static void FETCH(f_s8_z24)( const struct swrast_texture_image *texImage,
/* only return Z, not stencil data */
const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
- texel[0] = ((*src) & 0x00ffffff) * scale;
+ texel[0] = (GLfloat) (((*src) & 0x00ffffff) * scale);
ASSERT(texImage->Base.TexFormat == MESA_FORMAT_S8_Z24 ||
texImage->Base.TexFormat == MESA_FORMAT_X8_Z24);
ASSERT(texel[0] >= 0.0F);
diff --git a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
index 02c283da4..bbc020539 100644
--- a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
+++ b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
@@ -140,7 +140,7 @@ static inline float conv_i10_to_norm_float(const struct gl_context *ctx, int i10
(ctx->API == API_OPENGL_CORE && ctx->Version >= 42)) {
/* Equation 2.3 above. */
float f = ((float) val.x) / 511.0F;
- return MAX2(f, -1.0);
+ return MAX2(f, -1.0f);
} else {
/* Equation 2.2 above. */
return (2.0F * (float)val.x + 1.0F) * (1.0F / 1023.0F);
@@ -156,7 +156,7 @@ static inline float conv_i2_to_norm_float(const struct gl_context *ctx, int i2)
(ctx->API == API_OPENGL_CORE && ctx->Version >= 42)) {
/* Equation 2.3 above. */
float f = (float) val.x;
- return MAX2(f, -1.0);
+ return MAX2(f, -1.0f);
} else {
/* Equation 2.2 above. */
return (2.0F * (float)val.x + 1.0F) * (1.0F / 3.0F);
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index 1670409d4..f25a9dec3 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -1464,6 +1464,16 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
return;
}
+ if (ctx->Driver.GetTransformFeedbackVertexCount &&
+ (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
+ (ctx->Const.PrimitiveRestartInSoftware &&
+ ctx->Array._PrimitiveRestart) ||
+ !vbo_all_varyings_in_vbos(exec->array.inputs))) {
+ GLsizei n = ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
+ vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0);
+ return;
+ }
+
vbo_bind_arrays(ctx);
/* init most fields to zero */