aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_range.h89
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_surface.c55
-rw-r--r--mesalib/src/glsl/builtin_types.h19
-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_lexer.ll15
-rw-r--r--mesalib/src/glsl/glsl_parser.yy11
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp1
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h2
-rw-r--r--mesalib/src/glsl/glsl_types.cpp18
-rw-r--r--mesalib/src/glsl/glsl_types.h5
-rw-r--r--mesalib/src/glsl/ir.cpp40
-rw-r--r--mesalib/src/glsl/ir.h24
-rw-r--r--mesalib/src/glsl/ir_clone.cpp3
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp13
-rw-r--r--mesalib/src/glsl/ir_hv_accept.cpp5
-rw-r--r--mesalib/src/glsl/ir_optimization.h1
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp5
-rw-r--r--mesalib/src/glsl/ir_reader.cpp77
-rw-r--r--mesalib/src/glsl/ir_rvalue_visitor.cpp3
-rw-r--r--mesalib/src/glsl/ir_validate.cpp6
-rw-r--r--mesalib/src/glsl/lower_instructions.cpp35
-rw-r--r--mesalib/src/glsl/opt_algebraic.cpp17
-rw-r--r--mesalib/src/glsl/opt_tree_grafting.cpp4
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp1
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml69
-rwxr-xr-xmesalib/src/mapi/glapi/gen/gl_API.xml3
-rw-r--r--mesalib/src/mesa/drivers/common/driverfuncs.c3
-rw-r--r--mesalib/src/mesa/main/attrib.c15
-rw-r--r--mesalib/src/mesa/main/context.c5
-rw-r--r--mesalib/src/mesa/main/dd.h9
-rw-r--r--mesalib/src/mesa/main/enable.c18
-rw-r--r--mesalib/src/mesa/main/fbobject.c62
-rw-r--r--mesalib/src/mesa/main/get.c12
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py10
-rw-r--r--mesalib/src/mesa/main/mtypes.h19
-rw-r--r--mesalib/src/mesa/main/multisample.c52
-rw-r--r--mesalib/src/mesa/main/multisample.h6
-rw-r--r--mesalib/src/mesa/main/queryobj.c11
-rw-r--r--mesalib/src/mesa/main/shared.c2
-rw-r--r--mesalib/src/mesa/main/teximage.c240
-rw-r--r--mesalib/src/mesa/main/teximage.h11
-rw-r--r--mesalib/src/mesa/main/texobj.c96
-rw-r--r--mesalib/src/mesa/main/texparam.c16
-rw-r--r--mesalib/src/mesa/main/texstate.c2
-rw-r--r--mesalib/src/mesa/main/version.c94
-rw-r--r--mesalib/src/mesa/main/version.h3
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp10
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp7
49 files changed, 1067 insertions, 162 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_range.h b/mesalib/src/gallium/auxiliary/util/u_range.h
new file mode 100644
index 000000000..4b1d0d1be
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/util/u_range.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2013 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+/**
+ * @file
+ * 1D integer range, capable of the union and intersection operations.
+ *
+ * It only maintains a single interval which is extended when the union is
+ * done. This implementation is partially thread-safe (readers are not
+ * protected by a lock).
+ *
+ * @author Marek Olšák
+ */
+
+#ifndef U_RANGE_H
+#define U_RANGE_H
+
+#include "os/os_thread.h"
+
+struct util_range {
+ unsigned start; /* inclusive */
+ unsigned end; /* exclusive */
+
+ /* for the range to be consistent with multiple contexts: */
+ pipe_mutex write_mutex;
+};
+
+
+static INLINE void
+util_range_set_empty(struct util_range *range)
+{
+ range->start = ~0;
+ range->end = 0;
+}
+
+/* This is like a union of two sets. */
+static INLINE void
+util_range_add(struct util_range *range, unsigned start, unsigned end)
+{
+ if (start < range->start || end > range->end) {
+ pipe_mutex_lock(range->write_mutex);
+ range->start = MIN2(start, range->start);
+ range->end = MAX2(end, range->end);
+ pipe_mutex_unlock(range->write_mutex);
+ }
+}
+
+static INLINE boolean
+util_ranges_intersect(struct util_range *range, unsigned start, unsigned end)
+{
+ return MAX2(start, range->start) < MIN2(end, range->end);
+}
+
+
+/* Init/deinit */
+
+static INLINE void
+util_range_init(struct util_range *range)
+{
+ pipe_mutex_init(range->write_mutex);
+ util_range_set_empty(range);
+}
+
+static INLINE void
+util_range_destroy(struct util_range *range)
+{
+ pipe_mutex_destroy(range->write_mutex);
+}
+
+#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.c b/mesalib/src/gallium/auxiliary/util/u_surface.c
index b948b46d2..5c3a655d6 100644
--- a/mesalib/src/gallium/auxiliary/util/u_surface.c
+++ b/mesalib/src/gallium/auxiliary/util/u_surface.c
@@ -322,21 +322,58 @@ util_clear_render_target(struct pipe_context *pipe,
assert(dst->texture);
if (!dst->texture)
return;
- /* XXX: should handle multiple layers */
- dst_map = pipe_transfer_map(pipe,
- dst->texture,
- dst->u.tex.level,
- dst->u.tex.first_layer,
- PIPE_TRANSFER_WRITE,
- dstx, dsty, width, height, &dst_trans);
+
+ if (dst->texture->target == PIPE_BUFFER) {
+ /*
+ * The fill naturally works on the surface format, however
+ * the transfer uses resource format which is just bytes for buffers.
+ */
+ unsigned dx, w;
+ unsigned pixstride = util_format_get_blocksize(dst->format);
+ dx = (dst->u.buf.first_element + dstx) * pixstride;
+ w = width * pixstride;
+ dst_map = pipe_transfer_map(pipe,
+ dst->texture,
+ 0, 0,
+ PIPE_TRANSFER_WRITE,
+ dx, 0, w, 1,
+ &dst_trans);
+ }
+ else {
+ /* XXX: should handle multiple layers */
+ dst_map = pipe_transfer_map(pipe,
+ dst->texture,
+ dst->u.tex.level,
+ dst->u.tex.first_layer,
+ PIPE_TRANSFER_WRITE,
+ dstx, dsty, width, height, &dst_trans);
+
+ }
assert(dst_map);
if (dst_map) {
+ enum pipe_format format = dst->format;
assert(dst_trans->stride > 0);
- util_pack_color(color->f, dst->texture->format, &uc);
- util_fill_rect(dst_map, dst->texture->format,
+ if (util_format_is_pure_integer(format)) {
+ /*
+ * We expect int/uint clear values here, though some APIs
+ * might disagree (but in any case util_pack_color()
+ * couldn't handle it)...
+ */
+ if (util_format_is_pure_sint(format)) {
+ util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1);
+ }
+ else {
+ assert(util_format_is_pure_uint(format));
+ util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
+ }
+ }
+ else {
+ util_pack_color(color->f, dst->format, &uc);
+ }
+ util_fill_rect(dst_map, dst->format,
dst_trans->stride,
0, 0, width, height, &uc);
diff --git a/mesalib/src/glsl/builtin_types.h b/mesalib/src/glsl/builtin_types.h
index c78c2d270..acd2d76d5 100644
--- a/mesalib/src/glsl/builtin_types.h
+++ b/mesalib/src/glsl/builtin_types.h
@@ -347,3 +347,22 @@ const glsl_type glsl_type::builtin_ARB_texture_cube_map_array_types[] = {
GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT, "usamplerCubeArray"),
};
/*@}*/
+
+/** \name Sampler types added by GL_ARB_texture_multisample
+ */
+/*@{*/
+const glsl_type glsl_type::builtin_ARB_texture_multisample_types[] = {
+ glsl_type(GL_SAMPLER_2D_MULTISAMPLE,
+ GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT, "sampler2DMS"),
+ glsl_type(GL_INT_SAMPLER_2D_MULTISAMPLE,
+ GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT, "isampler2DMS"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,
+ GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT, "usampler2DMS"),
+ glsl_type(GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT, "sampler2DMSArray"),
+ glsl_type(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT, "isampler2DMSArray"),
+ glsl_type(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT, "usampler2DMSArray"),
+};
+/*@}*/
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index ccee7746e..53c4c51cd 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -849,6 +849,7 @@ initialize_vs_variables(exec_list *instructions,
generate_130_vs_variables(instructions, state, true);
break;
case 140:
+ case 150:
generate_130_vs_variables(instructions, state, false);
break;
default:
@@ -1140,6 +1141,7 @@ initialize_fs_variables(exec_list *instructions,
generate_130_fs_variables(instructions, state);
break;
case 140:
+ case 150:
generate_140_fs_variables(instructions, state);
break;
default:
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index e927c7cb7..d6afe8814 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -1230,6 +1230,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
if (extensions->ARB_shading_language_packing)
add_builtin_define(parser, "GL_ARB_shading_language_packing", 1);
+
+ if (extensions->ARB_texture_multisample)
+ add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
}
}
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index ddc9f8073..008ef303d 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -315,6 +315,15 @@ usamplerCube KEYWORD(130, 300, 130, 300, USAMPLERCUBE);
usampler1DArray KEYWORD(130, 300, 130, 0, USAMPLER1DARRAY);
usampler2DArray KEYWORD(130, 300, 130, 300, USAMPLER2DARRAY);
+ /* additional keywords in ARB_texture_multisample, included in GLSL 1.50 */
+ /* these are reserved but not defined in GLSL 3.00 */
+sampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, SAMPLER2DMS);
+isampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, ISAMPLER2DMS);
+usampler2DMS KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, USAMPLER2DMS);
+sampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, SAMPLER2DMSARRAY);
+isampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, ISAMPLER2DMSARRAY);
+usampler2DMSArray KEYWORD_WITH_ALT(150, 300, 150, 0, yyextra->ARB_texture_multisample_enable, USAMPLER2DMSARRAY);
+
samplerCubeArray {
if (yyextra->ARB_texture_cube_map_array_enable)
return SAMPLERCUBEARRAY;
@@ -531,12 +540,6 @@ atomic_uint KEYWORD(0, 300, 0, 0, ATOMIC_UINT);
patch KEYWORD(0, 300, 0, 0, PATCH);
sample KEYWORD(0, 300, 0, 0, SAMPLE);
subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
-sampler2DMS KEYWORD(0, 300, 0, 0, SAMPLER2DMS);
-isampler2DMS KEYWORD(0, 300, 0, 0, ISAMPLER2DMS);
-usampler2DMS KEYWORD(0, 300, 0, 0, USAMPLER2DMS);
-sampler2DMSArray KEYWORD(0, 300, 0, 0, SAMPLER2DMSARRAY);
-isampler2DMSArray KEYWORD(0, 300, 0, 0, ISAMPLER2DMSARRAY);
-usampler2DMSArray KEYWORD(0, 300, 0, 0, USAMPLER2DMSARRAY);
[_a-zA-Z][_a-zA-Z0-9]* {
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index 154ce2d09..f52ed9b0a 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -109,6 +109,8 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
%token USAMPLER2DARRAY USAMPLERCUBEARRAY
%token SAMPLER2DRECT ISAMPLER2DRECT USAMPLER2DRECT SAMPLER2DRECTSHADOW
%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER
+%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
+%token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
%token SAMPLEREXTERNALOES
%token STRUCT VOID_TOK WHILE
%token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
@@ -140,8 +142,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
%token SAMPLER3DRECT
%token SIZEOF CAST NAMESPACE USING
%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE
-%token SUBROUTINE SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS SAMPLER2DMSARRAY
-%token ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
+%token SUBROUTINE
%token ERROR_TOK
@@ -1462,6 +1463,12 @@ basic_type_specifier_nonarray:
| USAMPLER2DARRAY { $$ = "usampler2DArray"; }
| USAMPLERBUFFER { $$ = "usamplerBuffer"; }
| USAMPLERCUBEARRAY { $$ = "usamplerCubeArray"; }
+ | SAMPLER2DMS { $$ = "sampler2DMS"; }
+ | ISAMPLER2DMS { $$ = "isampler2DMS"; }
+ | USAMPLER2DMS { $$ = "usampler2DMS"; }
+ | SAMPLER2DMSARRAY { $$ = "sampler2DMSArray"; }
+ | ISAMPLER2DMSARRAY { $$ = "isampler2DMSArray"; }
+ | USAMPLER2DMSARRAY { $$ = "usampler2DMSArray"; }
;
precision_qualifier:
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index df1714850..9d7de3381 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -467,6 +467,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(OES_standard_derivatives, false, false, true, false, true, OES_standard_derivatives),
EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array),
EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing),
+ EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample),
};
#undef EXT
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 1815bb9b9..ad296f0ea 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -284,6 +284,8 @@ struct _mesa_glsl_parse_state {
bool ARB_texture_cube_map_array_warn;
bool ARB_shading_language_packing_enable;
bool ARB_shading_language_packing_warn;
+ bool ARB_texture_multisample_enable;
+ bool ARB_texture_multisample_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 82aeb84ed..a783dcc3b 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -198,6 +198,8 @@ glsl_type::sampler_index() const
return TEXTURE_BUFFER_INDEX;
case GLSL_SAMPLER_DIM_EXTERNAL:
return TEXTURE_EXTERNAL_INDEX;
+ case GLSL_SAMPLER_DIM_MS:
+ return (t->sampler_array) ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX;
default:
assert(!"Should not get here.");
return TEXTURE_BUFFER_INDEX;
@@ -345,6 +347,16 @@ glsl_type::generate_ARB_texture_cube_map_array_types(glsl_symbol_table *symtab,
}
void
+glsl_type::generate_ARB_texture_multisample_types(glsl_symbol_table *symtab,
+ bool warn)
+{
+ bool skip_1d = false;
+ add_types_to_symbol_table(symtab, builtin_ARB_texture_multisample_types,
+ Elements(builtin_ARB_texture_multisample_types),
+ warn, skip_1d);
+}
+
+void
_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
{
if (state->es_shader) {
@@ -373,6 +385,7 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
glsl_type::generate_130_types(state->symbols, true, skip_1d);
break;
case 140:
+ case 150:
glsl_type::generate_140_types(state->symbols);
break;
default:
@@ -412,6 +425,11 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
glsl_type::generate_ARB_texture_cube_map_array_types(state->symbols,
state->ARB_texture_cube_map_array_warn);
}
+
+ if (state->ARB_texture_multisample_enable) {
+ glsl_type::generate_ARB_texture_multisample_types(state->symbols,
+ state->ARB_texture_multisample_warn);
+ }
}
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index 8cfd8dd02..79304269d 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -67,7 +67,8 @@ enum glsl_sampler_dim {
GLSL_SAMPLER_DIM_CUBE,
GLSL_SAMPLER_DIM_RECT,
GLSL_SAMPLER_DIM_BUF,
- GLSL_SAMPLER_DIM_EXTERNAL
+ GLSL_SAMPLER_DIM_EXTERNAL,
+ GLSL_SAMPLER_DIM_MS
};
enum glsl_interface_packing {
@@ -561,6 +562,7 @@ private:
static const glsl_type builtin_EXT_texture_buffer_object_types[];
static const glsl_type builtin_OES_EGL_image_external_types[];
static const glsl_type builtin_ARB_texture_cube_map_array_types[];
+ static const glsl_type builtin_ARB_texture_multisample_types[];
/*@}*/
/**
@@ -586,6 +588,7 @@ private:
static void generate_OES_texture_3D_types(glsl_symbol_table *, bool);
static void generate_OES_EGL_image_external_types(glsl_symbol_table *, bool);
static void generate_ARB_texture_cube_map_array_types(glsl_symbol_table *, bool);
+ static void generate_ARB_texture_multisample_types(glsl_symbol_table *, bool);
/*@}*/
/**
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 954995db3..2eb3af695 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -195,34 +195,6 @@ ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
this->set_lhs(lhs);
}
-
-ir_expression::ir_expression(int op, const struct glsl_type *type,
- ir_rvalue *op0)
-{
- assert(get_num_operands(ir_expression_operation(op)) == 1);
- this->ir_type = ir_type_expression;
- this->type = type;
- this->operation = ir_expression_operation(op);
- this->operands[0] = op0;
- this->operands[1] = NULL;
- this->operands[2] = NULL;
- this->operands[3] = NULL;
-}
-
-ir_expression::ir_expression(int op, const struct glsl_type *type,
- ir_rvalue *op0, ir_rvalue *op1)
-{
- assert(((op1 == NULL) && (get_num_operands(ir_expression_operation(op)) == 1))
- || (get_num_operands(ir_expression_operation(op)) == 2));
- this->ir_type = ir_type_expression;
- this->type = type;
- this->operation = ir_expression_operation(op);
- this->operands[0] = op0;
- this->operands[1] = op1;
- this->operands[2] = NULL;
- this->operands[3] = NULL;
-}
-
ir_expression::ir_expression(int op, const struct glsl_type *type,
ir_rvalue *op0, ir_rvalue *op1,
ir_rvalue *op2, ir_rvalue *op3)
@@ -234,6 +206,12 @@ ir_expression::ir_expression(int op, const struct glsl_type *type,
this->operands[1] = op1;
this->operands[2] = op2;
this->operands[3] = op3;
+#ifndef NDEBUG
+ int num_operands = get_num_operands(this->operation);
+ for (int i = num_operands; i < 4; i++) {
+ assert(this->operands[i] == NULL);
+ }
+#endif
}
ir_expression::ir_expression(int op, ir_rvalue *op0)
@@ -438,6 +416,9 @@ ir_expression::get_num_operands(ir_expression_operation op)
if (op <= ir_last_binop)
return 2;
+ if (op <= ir_last_triop)
+ return 3;
+
if (op == ir_quadop_vector)
return 4;
@@ -524,6 +505,7 @@ static const char *const operator_strs[] = {
"pow",
"packHalf2x16_split",
"ubo_load",
+ "lrp",
"vector",
};
@@ -1325,7 +1307,7 @@ ir_dereference::is_lvalue() const
}
-static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txs" };
+static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs" };
const char *ir_texture::opcode_string()
{
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index 1e09988e5..393b48673 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -1118,6 +1118,13 @@ enum ir_expression_operation {
*/
ir_last_binop = ir_binop_ubo_load,
+ ir_triop_lrp,
+
+ /**
+ * A sentinel marking the last of the ternary operations.
+ */
+ ir_last_triop = ir_triop_lrp,
+
ir_quadop_vector,
/**
@@ -1128,25 +1135,20 @@ enum ir_expression_operation {
class ir_expression : public ir_rvalue {
public:
+ ir_expression(int op, const struct glsl_type *type,
+ ir_rvalue *op0, ir_rvalue *op1 = NULL,
+ ir_rvalue *op2 = NULL, ir_rvalue *op3 = NULL);
+
/**
* Constructor for unary operation expressions
*/
- ir_expression(int op, const struct glsl_type *type, ir_rvalue *);
ir_expression(int op, ir_rvalue *);
/**
* Constructor for binary operation expressions
*/
- ir_expression(int op, const struct glsl_type *type,
- ir_rvalue *, ir_rvalue *);
ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
- /**
- * Constructor for quad operator expressions
- */
- ir_expression(int op, const struct glsl_type *type,
- ir_rvalue *, ir_rvalue *, ir_rvalue *, ir_rvalue *);
-
virtual ir_expression *as_expression()
{
return this;
@@ -1422,6 +1424,7 @@ enum ir_texture_opcode {
ir_txl, /**< Texture look-up with explicit LOD */
ir_txd, /**< Texture look-up with partial derivatvies */
ir_txf, /**< Texel fetch with explicit LOD */
+ ir_txf_ms, /**< Multisample texture fetch */
ir_txs /**< Texture size */
};
@@ -1443,6 +1446,8 @@ enum ir_texture_opcode {
* (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>)
* (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
* (txf <type> <sampler> <coordinate> 0 <lod>)
+ * (txf_ms
+ * <type> <sampler> <coordinate> <sample_index>)
* (txs <type> <sampler> <lod>)
*/
class ir_texture : public ir_rvalue {
@@ -1509,6 +1514,7 @@ public:
union {
ir_rvalue *lod; /**< Floating point LOD */
ir_rvalue *bias; /**< Floating point LOD bias */
+ ir_rvalue *sample_index; /**< MSAA sample index */
struct {
ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */
ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index b94ff05df..4797451d7 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -252,6 +252,9 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
case ir_txs:
new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht);
break;
+ case ir_txf_ms:
+ new_tex->lod_info.sample_index = this->lod_info.sample_index->clone(mem_ctx, ht);
+ break;
case ir_txd:
new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht);
new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht);
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index 86b863f31..c2d0dc46c 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -1248,6 +1248,19 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
}
break;
+ case ir_triop_lrp: {
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(op[1]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(op[2]->type->base_type == GLSL_TYPE_FLOAT);
+
+ unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
+ for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
+ data.f[c] = op[0]->value.f[c] * (1.0f - op[2]->value.f[c2]) +
+ (op[1]->value.f[c] * op[2]->value.f[c2]);
+ }
+ break;
+ }
+
case ir_quadop_vector:
for (unsigned c = 0; c < this->type->vector_elements; c++) {
switch (this->type->base_type) {
diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp
index 3ce895924..5fa75011e 100644
--- a/mesalib/src/glsl/ir_hv_accept.cpp
+++ b/mesalib/src/glsl/ir_hv_accept.cpp
@@ -226,6 +226,11 @@ ir_texture::accept(ir_hierarchical_visitor *v)
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
break;
+ case ir_txf_ms:
+ s = this->lod_info.sample_index->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ break;
case ir_txd:
s = this->lod_info.grad.dPdx->accept(v);
if (s != visit_continue)
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index 8f3301840..2454bbe6f 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -36,6 +36,7 @@
#define LOG_TO_LOG2 0x10
#define MOD_TO_FRACT 0x20
#define INT_DIV_TO_MUL_RCP 0x40
+#define LRP_TO_ARITH 0x80
/**
* \see class lower_packing_builtins_visitor
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index acc92dbf1..3bdea9bbc 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -260,7 +260,7 @@ void ir_print_visitor::visit(ir_texture *ir)
printf(" ");
}
- if (ir->op != ir_txf && ir->op != ir_txs) {
+ if (ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_txs) {
if (ir->projector)
ir->projector->accept(this);
else
@@ -287,6 +287,9 @@ void ir_print_visitor::visit(ir_texture *ir)
case ir_txs:
ir->lod_info.lod->accept(this);
break;
+ case ir_txf_ms:
+ ir->lod_info.sample_index->accept(this);
+ break;
case ir_txd:
printf("(");
ir->lod_info.grad.dPdx->accept(this);
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 405e75b64..22ce03b0d 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -676,15 +676,16 @@ ir_reader::read_expression(s_expression *expr)
{
s_expression *s_type;
s_symbol *s_op;
- s_expression *s_arg1;
+ s_expression *s_arg[3];
- s_pattern pat[] = { "expression", s_type, s_op, s_arg1 };
+ s_pattern pat[] = { "expression", s_type, s_op, s_arg[0] };
if (!PARTIAL_MATCH(expr, pat)) {
ir_read_error(expr, "expected (expression <type> <operator> "
"<operand> [<operand>])");
return NULL;
}
- s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel
+ s_arg[1] = (s_expression *) s_arg[0]->next; // may be tail sentinel
+ s_arg[2] = (s_expression *) s_arg[1]->next; // may be tail sentinel or NULL
const glsl_type *type = read_type(s_type);
if (type == NULL)
@@ -697,35 +698,27 @@ ir_reader::read_expression(s_expression *expr)
return NULL;
}
- unsigned num_operands = ir_expression::get_num_operands(op);
- if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) {
- ir_read_error(expr, "expected (expression <type> %s <operand>)",
- s_op->value());
+ int num_operands = -3; /* skip "expression" <type> <operation> */
+ foreach_list(n, &((s_list *) expr)->subexpressions)
+ ++num_operands;
+
+ int expected_operands = ir_expression::get_num_operands(op);
+ if (num_operands != expected_operands) {
+ ir_read_error(expr, "found %d expression operands, expected %d",
+ num_operands, expected_operands);
return NULL;
}
- ir_rvalue *arg1 = read_rvalue(s_arg1);
- ir_rvalue *arg2 = NULL;
- if (arg1 == NULL) {
- ir_read_error(NULL, "when reading first operand of %s", s_op->value());
- return NULL;
- }
-
- if (num_operands == 2) {
- if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) {
- ir_read_error(expr, "expected (expression <type> %s <operand> "
- "<operand>)", s_op->value());
- return NULL;
- }
- arg2 = read_rvalue(s_arg2);
- if (arg2 == NULL) {
- ir_read_error(NULL, "when reading second operand of %s",
- s_op->value());
- return NULL;
+ ir_rvalue *arg[3] = {NULL, NULL, NULL};
+ for (int i = 0; i < num_operands; i++) {
+ arg[i] = read_rvalue(s_arg[i]);
+ if (arg[i] == NULL) {
+ ir_read_error(NULL, "when reading operand #%d of %s", i, s_op->value());
+ return NULL;
}
}
- return new(mem_ctx) ir_expression(op, type, arg1, arg2);
+ return new(mem_ctx) ir_expression(op, type, arg[0], arg[1], arg[2]);
}
ir_swizzle *
@@ -918,6 +911,7 @@ ir_reader::read_texture(s_expression *expr)
s_expression *s_proj = NULL;
s_list *s_shadow = NULL;
s_expression *s_lod = NULL;
+ s_expression *s_sample_index = NULL;
ir_texture_opcode op = ir_tex; /* silence warning */
@@ -925,6 +919,8 @@ ir_reader::read_texture(s_expression *expr)
{ "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
s_pattern txf_pattern[] =
{ "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
+ s_pattern txf_ms_pattern[] =
+ { "txf_ms", s_type, s_sampler, s_coord, s_sample_index };
s_pattern txs_pattern[] =
{ "txs", s_type, s_sampler, s_lod };
s_pattern other_pattern[] =
@@ -934,6 +930,8 @@ ir_reader::read_texture(s_expression *expr)
op = ir_tex;
} else if (MATCH(expr, txf_pattern)) {
op = ir_txf;
+ } else if (MATCH(expr, txf_ms_pattern)) {
+ op = ir_txf_ms;
} else if (MATCH(expr, txs_pattern)) {
op = ir_txs;
} else if (MATCH(expr, other_pattern)) {
@@ -973,18 +971,20 @@ ir_reader::read_texture(s_expression *expr)
return NULL;
}
- // Read texel offset - either 0 or an rvalue.
- s_int *si_offset = SX_AS_INT(s_offset);
- if (si_offset == NULL || si_offset->value() != 0) {
- tex->offset = read_rvalue(s_offset);
- if (tex->offset == NULL) {
- ir_read_error(s_offset, "expected 0 or an expression");
- return NULL;
- }
+ if (op != ir_txf_ms) {
+ // Read texel offset - either 0 or an rvalue.
+ s_int *si_offset = SX_AS_INT(s_offset);
+ if (si_offset == NULL || si_offset->value() != 0) {
+ tex->offset = read_rvalue(s_offset);
+ if (tex->offset == NULL) {
+ ir_read_error(s_offset, "expected 0 or an expression");
+ return NULL;
+ }
+ }
}
}
- if (op != ir_txf && op != ir_txs) {
+ if (op != ir_txf && op != ir_txf_ms && op != ir_txs) {
s_int *proj_as_int = SX_AS_INT(s_proj);
if (proj_as_int && proj_as_int->value() == 1) {
tex->projector = NULL;
@@ -1027,6 +1027,13 @@ ir_reader::read_texture(s_expression *expr)
return NULL;
}
break;
+ case ir_txf_ms:
+ tex->lod_info.sample_index = read_rvalue(s_sample_index);
+ if (tex->lod_info.sample_index == NULL) {
+ ir_read_error(NULL, "when reading sample_index in (txf_ms ...)");
+ return NULL;
+ }
+ break;
case ir_txd: {
s_expression *s_dx, *s_dy;
s_pattern dxdy_pat[] = { s_dx, s_dy };
diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp
index b34a419e8..543c54496 100644
--- a/mesalib/src/glsl/ir_rvalue_visitor.cpp
+++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp
@@ -66,6 +66,9 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
case ir_txs:
handle_rvalue(&ir->lod_info.lod);
break;
+ case ir_txf_ms:
+ handle_rvalue(&ir->lod_info.sample_index);
+ break;
case ir_txd:
handle_rvalue(&ir->lod_info.grad.dPdx);
handle_rvalue(&ir->lod_info.grad.dPdy);
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index d8cafd55f..24ea506dc 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -468,6 +468,12 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[1]->type == glsl_type::uint_type);
break;
+ case ir_triop_lrp:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
+ assert(ir->operands[0]->type == ir->operands[1]->type);
+ assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type);
+ break;
+
case ir_quadop_vector:
/* The vector operator collects some number of scalars and generates a
* vector from them.
diff --git a/mesalib/src/glsl/lower_instructions.cpp b/mesalib/src/glsl/lower_instructions.cpp
index a8ef7654e..1ce7b7c9d 100644
--- a/mesalib/src/glsl/lower_instructions.cpp
+++ b/mesalib/src/glsl/lower_instructions.cpp
@@ -37,6 +37,7 @@
* - POW_TO_EXP2
* - LOG_TO_LOG2
* - MOD_TO_FRACT
+ * - LRP_TO_ARITH
*
* SUB_TO_ADD_NEG:
* ---------------
@@ -79,13 +80,20 @@
* Many GPUs don't have a MOD instruction (945 and 965 included), and
* if we have to break it down like this anyway, it gives an
* opportunity to do things like constant fold the (1.0 / op1) easily.
+ *
+ * LRP_TO_ARITH:
+ * -------------
+ * Converts ir_triop_lrp to (op0 * (1.0f - op2)) + (op1 * op2).
*/
#include "main/core.h" /* for M_LOG2E */
#include "glsl_types.h"
#include "ir.h"
+#include "ir_builder.h"
#include "ir_optimization.h"
+using namespace ir_builder;
+
class lower_instructions_visitor : public ir_hierarchical_visitor {
public:
lower_instructions_visitor(unsigned lower)
@@ -105,6 +113,7 @@ private:
void exp_to_exp2(ir_expression *);
void pow_to_exp2(ir_expression *);
void log_to_log2(ir_expression *);
+ void lrp_to_arith(ir_expression *);
};
/**
@@ -268,6 +277,27 @@ lower_instructions_visitor::mod_to_fract(ir_expression *ir)
this->progress = true;
}
+void
+lower_instructions_visitor::lrp_to_arith(ir_expression *ir)
+{
+ /* (lrp x y a) -> x*(1-a) + y*a */
+
+ /* Save op2 */
+ ir_variable *temp = new(ir) ir_variable(ir->operands[2]->type, "lrp_factor",
+ ir_var_temporary);
+ this->base_ir->insert_before(temp);
+ this->base_ir->insert_before(assign(temp, ir->operands[2]));
+
+ ir_constant *one = new(ir) ir_constant(1.0f);
+
+ ir->operation = ir_binop_add;
+ ir->operands[0] = mul(ir->operands[0], sub(one, temp));
+ ir->operands[1] = mul(ir->operands[1], temp);
+ ir->operands[2] = NULL;
+
+ this->progress = true;
+}
+
ir_visitor_status
lower_instructions_visitor::visit_leave(ir_expression *ir)
{
@@ -304,6 +334,11 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
pow_to_exp2(ir);
break;
+ case ir_triop_lrp:
+ if (lowering(LRP_TO_ARITH))
+ lrp_to_arith(ir);
+ break;
+
default:
return visit_continue;
}
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp
index 75948db16..70e016d22 100644
--- a/mesalib/src/glsl/opt_algebraic.cpp
+++ b/mesalib/src/glsl/opt_algebraic.cpp
@@ -186,12 +186,12 @@ ir_algebraic_visitor::swizzle_if_required(ir_expression *expr,
ir_rvalue *
ir_algebraic_visitor::handle_expression(ir_expression *ir)
{
- ir_constant *op_const[2] = {NULL, NULL};
- ir_expression *op_expr[2] = {NULL, NULL};
+ ir_constant *op_const[3] = {NULL, NULL, NULL};
+ ir_expression *op_expr[3] = {NULL, NULL, NULL};
ir_expression *temp;
unsigned int i;
- assert(ir->get_num_operands() <= 2);
+ assert(ir->get_num_operands() <= 3);
for (i = 0; i < ir->get_num_operands(); i++) {
if (ir->operands[i]->type->is_matrix())
return ir;
@@ -415,6 +415,17 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
break;
+ case ir_triop_lrp:
+ /* Operands are (x, y, a). */
+ if (is_vec_zero(op_const[2])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[0]);
+ } else if (is_vec_one(op_const[2])) {
+ this->progress = true;
+ return swizzle_if_required(ir, ir->operands[1]);
+ }
+ break;
+
default:
break;
}
diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp
index 113abb7b0..985540196 100644
--- a/mesalib/src/glsl/opt_tree_grafting.cpp
+++ b/mesalib/src/glsl/opt_tree_grafting.cpp
@@ -285,6 +285,10 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
if (do_graft(&ir->lod_info.lod))
return visit_stop;
break;
+ case ir_txf_ms:
+ if (do_graft(&ir->lod_info.sample_index))
+ return visit_stop;
+ break;
case ir_txd:
if (do_graft(&ir->lod_info.grad.dPdx) ||
do_graft(&ir->lod_info.grad.dPdy))
diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp
index 0fb4f5b16..8c0091e84 100644
--- a/mesalib/src/glsl/standalone_scaffolding.cpp
+++ b/mesalib/src/glsl/standalone_scaffolding.cpp
@@ -102,6 +102,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
ctx->Extensions.ARB_shading_language_packing = true;
ctx->Extensions.OES_standard_derivatives = true;
ctx->Extensions.ARB_texture_cube_map_array = true;
+ ctx->Extensions.ARB_texture_multisample = true;
ctx->Const.GLSLVersion = 120;
diff --git a/mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml b/mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml
new file mode 100644
index 000000000..f0dd4f5f7
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+<OpenGLAPI>
+
+<category name="GL_ARB_texture_multisample" number="67">
+
+ <enum name="SAMPLE_POSITION" value="0x8E50"/>
+ <enum name="SAMPLE_MASK" value="0x8E51"/>
+ <enum name="SAMPLE_MASK_VALUE" value="0x8E52"/>
+
+ <enum name="TEXTURE_2D_MULTISAMPLE" value="0x9100"/>
+ <enum name="PROXY_TEXTURE_2D_MULTISAMPLE" value="0x9101"/>
+ <enum name="TEXTURE_2D_MULTISAMPLE_ARRAY" value="0x9102"/>
+ <enum name="PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY" value="0x9103"/>
+
+ <enum name="MAX_SAMPLE_MASK_WORDS" value="0x8E59"/>
+ <enum name="MAX_COLOR_TEXTURE_SAMPLES" value="0x910E"/>
+ <enum name="MAX_DEPTH_TEXTURE_SAMPLES" value="0x910F"/>
+ <enum name="MAX_INTEGER_SAMPLES" value="0x9110"/>
+
+ <enum name="TEXTURE_BINDING_2D_MULTISAMPLE" value="0x9104"/>
+ <enum name="TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY" value="0x9105"/>
+
+ <enum name="TEXTURE_SAMPLES" value="0x9106"/>
+ <enum name="TEXTURE_FIXED_SAMPLE_LOCATIONS" value="0x9107"/>
+
+ <enum name="SAMPLER_2D_MULTISAMPLE" value="0x9108"/>
+ <enum name="INT_SAMPLER_2D_MULTISAMPLE" value="0x9109"/>
+ <enum name="UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE" value="0x910A"/>
+ <enum name="SAMPLER_2D_MULTISAMPLE_ARRAY" value="0x910B"/>
+ <enum name="INT_SAMPLER_2D_MULTISAMPLE_ARRAY" value="0x910C"/>
+ <enum name="UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY" value="0x910D"/>
+
+ <function name="TexImage2DMultisample" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="internalformat" type="GLint"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ <param name="fixedsamplelocations" type="GLboolean"/>
+ </function>
+
+ <function name="TexImage3DMultisample" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="internalformat" type="GLint"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ <param name="depth" type="GLsizei"/>
+ <param name="fixedsamplelocations" type="GLboolean"/>
+ </function>
+
+ <function name="GetMultisamplefv" offset="assign">
+ <param name="pname" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="val" type="GLfloat *"/>
+ </function>
+
+ <function name="SampleMaski" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="mask" type="GLbitfield"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml
index a3e1351b5..e313013f3 100755
--- a/mesalib/src/mapi/glapi/gen/gl_API.xml
+++ b/mesalib/src/mapi/glapi/gen/gl_API.xml
@@ -8179,7 +8179,8 @@
<xi:include href="ARB_sync.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
-<!-- 67. GL_ARB_texture_multisample -->
+<xi:include href="ARB_texture_multisample.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<!-- 68. GL_ARB_vertex_array_bgra -->
<xi:include href="ARB_draw_buffers_blend.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c
index 43c9de97f..731d46658 100644
--- a/mesalib/src/mesa/drivers/common/driverfuncs.c
+++ b/mesalib/src/mesa/drivers/common/driverfuncs.c
@@ -209,6 +209,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
/* GL_ARB_texture_storage */
driver->AllocTextureStorage = _swrast_AllocTextureStorage;
+
+ /* GL_ARB_texture_multisample */
+ driver->GetSamplePosition = NULL;
}
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index a95128328..3b991bcac 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -130,6 +130,9 @@ struct gl_enable_attrib
GLboolean VertexProgramPointSize;
GLboolean VertexProgramTwoSide;
+ /* GL_ARB_fragment_program */
+ GLboolean FragmentProgram;
+
/* GL_ARB_point_sprite / GL_NV_point_sprite */
GLboolean PointSprite;
GLboolean FragmentShaderATI;
@@ -316,6 +319,10 @@ _mesa_PushAttrib(GLbitfield mask)
attr->VertexProgram = ctx->VertexProgram.Enabled;
attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
+
+ /* GL_ARB_fragment_program */
+ attr->FragmentProgram = ctx->FragmentProgram.Enabled;
+
save_attrib_data(&head, GL_ENABLE_BIT, attr);
/* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
@@ -607,6 +614,11 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
enable->VertexProgramTwoSide,
GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
+ /* GL_ARB_fragment_program */
+ TEST_AND_UPDATE(ctx->FragmentProgram.Enabled,
+ enable->FragmentProgram,
+ GL_FRAGMENT_PROGRAM_ARB);
+
/* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled,
GL_FRAMEBUFFER_SRGB);
@@ -767,6 +779,9 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate)
continue;
else if (obj->Target == GL_TEXTURE_EXTERNAL_OES)
continue;
+ else if (obj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
+ obj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
+ continue;
target = obj->Target;
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index 02acfc2aa..cdcf7adfa 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -661,6 +661,11 @@ _mesa_init_constants(struct gl_context *ctx)
/* ES 3.0 or ARB_ES3_compatibility */
ctx->Const.MaxElementIndex = 0xffffffffu;
+
+ /* GL_ARB_texture_multisample */
+ ctx->Const.MaxColorTextureSamples = 1;
+ ctx->Const.MaxDepthTextureSamples = 1;
+ ctx->Const.MaxIntegerSamples = 1;
}
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index 9c818ccd8..4860d4d12 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -638,6 +638,7 @@ struct dd_function_table {
struct gl_query_object * (*NewQueryObject)(struct gl_context *ctx, GLuint id);
void (*DeleteQuery)(struct gl_context *ctx, struct gl_query_object *q);
void (*BeginQuery)(struct gl_context *ctx, struct gl_query_object *q);
+ void (*QueryCounter)(struct gl_context *ctx, struct gl_query_object *q);
void (*EndQuery)(struct gl_context *ctx, struct gl_query_object *q);
void (*CheckQuery)(struct gl_context *ctx, struct gl_query_object *q);
void (*WaitQuery)(struct gl_context *ctx, struct gl_query_object *q);
@@ -833,6 +834,14 @@ struct dd_function_table {
* This should be equivalent to glGetInteger64v(GL_TIMESTAMP);
*/
uint64_t (*GetTimestamp)(struct gl_context *ctx);
+
+ /**
+ * \name GL_ARB_texture_multisample
+ */
+ void (*GetSamplePosition)(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLuint index,
+ GLfloat *outValue);
};
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index 7e85fdfb3..b688f050b 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -1013,6 +1013,17 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
}
break;
+ /* ARB_texture_multisample */
+ case GL_SAMPLE_MASK:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum_error;
+ CHECK_EXTENSION(ARB_texture_multisample, cap);
+ if (ctx->Multisample.SampleMask == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleMask = state;
+ break;
+
default:
goto invalid_enum_error;
}
@@ -1583,6 +1594,13 @@ _mesa_IsEnabled( GLenum cap )
CHECK_EXTENSION(OES_EGL_image_external);
return is_texture_enabled(ctx, TEXTURE_EXTERNAL_BIT);
+ /* ARB_texture_multisample */
+ case GL_SAMPLE_MASK:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum_error;
+ CHECK_EXTENSION(ARB_texture_multisample);
+ return ctx->Multisample.SampleMask;
+
default:
goto invalid_enum_error;
}
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 89bc57509..d6acc5896 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -745,6 +745,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
GLenum intFormat = GL_NONE; /* color buffers' internal format */
GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
GLint numSamples = -1;
+ GLint fixedSampleLocations = -1;
GLint i;
GLuint j;
@@ -814,12 +815,29 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
f = texImg->_BaseFormat;
attFormat = texImg->TexFormat;
numImages++;
+
if (!is_format_color_renderable(ctx, attFormat, texImg->InternalFormat) &&
!is_legal_depth_format(ctx, f)) {
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
fbo_incomplete("texture attachment incomplete", -1);
return;
}
+
+ if (numSamples < 0)
+ numSamples = texImg->NumSamples;
+ else if (numSamples != texImg->NumSamples) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent sample count", -1);
+ return;
+ }
+
+ if (fixedSampleLocations < 0)
+ fixedSampleLocations = texImg->FixedSampleLocations;
+ else if (fixedSampleLocations != texImg->FixedSampleLocations) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent fixed sample locations", -1);
+ return;
+ }
}
else if (att->Type == GL_RENDERBUFFER_EXT) {
minWidth = MIN2(minWidth, att->Renderbuffer->Width);
@@ -829,24 +847,35 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
f = att->Renderbuffer->InternalFormat;
attFormat = att->Renderbuffer->Format;
numImages++;
+
+ if (numSamples < 0)
+ numSamples = att->Renderbuffer->NumSamples;
+ else if (numSamples != att->Renderbuffer->NumSamples) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent sample count", -1);
+ return;
+ }
+
+ /* RENDERBUFFER has fixedSampleLocations implicitly true */
+ if (fixedSampleLocations < 0)
+ fixedSampleLocations = GL_TRUE;
+ else if (fixedSampleLocations != GL_TRUE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent fixed sample locations", -1);
+ return;
+ }
}
else {
assert(att->Type == GL_NONE);
continue;
}
- if (att->Renderbuffer && numSamples < 0) {
- /* first buffer */
- numSamples = att->Renderbuffer->NumSamples;
- }
-
/* check if integer color */
fb->_IntegerColor = _mesa_is_format_integer_color(attFormat);
- /* Error-check width, height, format, samples
- */
+ /* Error-check width, height, format */
if (numImages == 1) {
- /* save format, num samples */
+ /* save format */
if (i >= 0) {
intFormat = f;
}
@@ -866,12 +895,6 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
return;
}
}
- if (att->Renderbuffer &&
- att->Renderbuffer->NumSamples != numSamples) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
- fbo_incomplete("inconsistant number of samples", i);
- return;
- }
}
/* Check that the format is valid. (MESA_FORMAT_NONE means unsupported)
@@ -2069,7 +2092,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
err = (texObj->Target != GL_TEXTURE_3D) &&
(texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
(texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
- (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY);
+ (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
+ (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
}
else {
/* Make sure textarget is consistent with the texture's type */
@@ -2103,7 +2127,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
(texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) ||
- (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)) {
+ (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
+ (texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
if (zoffset < 0 ||
zoffset >= (GLint) ctx->Const.MaxArrayTextureLayers) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -2255,6 +2280,11 @@ _mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
error = (_mesa_is_gles(ctx) && ctx->Version < 30)
|| !ctx->Extensions.EXT_texture_array;
break;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ error = _mesa_is_gles(ctx)
+ || !ctx->Extensions.ARB_texture_multisample;
+ break;
default:
error = GL_TRUE;
}
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index da1e01cb5..2399f9c9d 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -354,6 +354,7 @@ EXTRA_EXT(ARB_timer_query);
EXTRA_EXT(ARB_map_buffer_alignment);
EXTRA_EXT(ARB_texture_cube_map_array);
EXTRA_EXT(ARB_texture_buffer_range);
+EXTRA_EXT(ARB_texture_multisample);
static const int
extra_NV_primitive_restart[] = {
@@ -693,6 +694,8 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
case GL_TEXTURE_BINDING_RECTANGLE_NV:
case GL_TEXTURE_BINDING_EXTERNAL_OES:
case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
unit = ctx->Texture.CurrentUnit;
v->value_int =
ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name;
@@ -1632,6 +1635,15 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
goto invalid_enum;
v->value_int = ctx->UniformBufferBindings[index].Size;
return TYPE_INT;
+
+ /* ARB_texture_multisample / GL3.2 */
+ case GL_SAMPLE_MASK_VALUE:
+ if (index != 0)
+ goto invalid_value;
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_enum;
+ v->value_int = ctx->Multisample.SampleMaskValue;
+ return TYPE_INT;
}
invalid_enum:
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index 1b7d6ad8e..5022ddc40 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -658,6 +658,16 @@ descriptor=[
[ "TEXTURE_BUFFER_FORMAT_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ],
[ "TEXTURE_BUFFER_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ],
+# GL_ARB_texture_multisample / GL 3.2
+ [ "TEXTURE_BINDING_2D_MULTISAMPLE", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_INDEX, extra_ARB_texture_multisample" ],
+ [ "TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX, extra_ARB_texture_multisample" ],
+ [ "MAX_COLOR_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxColorTextureSamples), extra_ARB_texture_multisample" ],
+ [ "MAX_DEPTH_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxDepthTextureSamples), extra_ARB_texture_multisample" ],
+ [ "MAX_INTEGER_SAMPLES", "CONTEXT_INT(Const.MaxIntegerSamples), extra_ARB_texture_multisample" ],
+ [ "SAMPLE_MASK", "CONTEXT_BOOL(Multisample.SampleMask), extra_ARB_texture_multisample" ],
+ [ "MAX_SAMPLE_MASK_WORDS", "CONST(1), extra_ARB_texture_multisample" ],
+
+
# GL_ARB_sampler_objects / GL 3.3
[ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index b92f98e7d..a80944c81 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -993,6 +993,12 @@ struct gl_multisample_attrib
GLboolean SampleCoverage;
GLfloat SampleCoverageValue;
GLboolean SampleCoverageInvert;
+
+ /* ARB_texture_multisample / GL3.2 additions */
+ GLboolean SampleMask;
+ GLbitfield SampleMaskValue; /* GL spec defines this as an array but >32x MSAA is
+ * madness
+ */
};
@@ -1148,6 +1154,8 @@ struct gl_stencil_attrib
*/
typedef enum
{
+ TEXTURE_2D_MULTISAMPLE_INDEX,
+ TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX,
TEXTURE_CUBE_ARRAY_INDEX,
TEXTURE_BUFFER_INDEX,
TEXTURE_2D_ARRAY_INDEX,
@@ -1167,6 +1175,8 @@ typedef enum
* Used for Texture.Unit[]._ReallyEnabled flags.
*/
/*@{*/
+#define TEXTURE_2D_MULTISAMPLE_BIT (1 << TEXTURE_2D_MULTISAMPLE_INDEX)
+#define TEXTURE_2D_MULTISAMPLE_ARRAY_BIT (1 << TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX)
#define TEXTURE_CUBE_ARRAY_BIT (1 << TEXTURE_CUBE_ARRAY_INDEX)
#define TEXTURE_BUFFER_BIT (1 << TEXTURE_BUFFER_INDEX)
#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX)
@@ -1212,6 +1222,10 @@ struct gl_texture_image
GLuint Level; /**< Which mipmap level am I? */
/** Cube map face: index into gl_texture_object::Image[] array */
GLuint Face;
+
+ /** GL_ARB_texture_multisample */
+ GLuint NumSamples; /**< Sample count, or 0 for non-multisample */
+ GLboolean FixedSampleLocations; /**< Same sample locations for all pixels? */
};
@@ -3027,6 +3041,11 @@ struct gl_constants
* backslash character ('\') in GLSL source.
*/
GLboolean DisableGLSLLineContinuations;
+
+ /** GL_ARB_texture_multisample */
+ GLint MaxColorTextureSamples;
+ GLint MaxDepthTextureSamples;
+ GLint MaxIntegerSamples;
};
diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c
index f792ad01e..248494615 100644
--- a/mesalib/src/mesa/main/multisample.c
+++ b/mesalib/src/mesa/main/multisample.c
@@ -28,6 +28,7 @@
#include "main/macros.h"
#include "main/multisample.h"
#include "main/mtypes.h"
+#include "main/fbobject.h"
/**
@@ -59,4 +60,55 @@ _mesa_init_multisample(struct gl_context *ctx)
ctx->Multisample.SampleCoverage = GL_FALSE;
ctx->Multisample.SampleCoverageValue = 1.0;
ctx->Multisample.SampleCoverageInvert = GL_FALSE;
+
+ /* ARB_texture_multisample / GL3.2 additions */
+ ctx->Multisample.SampleMask = GL_FALSE;
+ ctx->Multisample.SampleMaskValue = ~(GLbitfield)0;
+}
+
+
+void GLAPIENTRY
+_mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ switch (pname) {
+ case GL_SAMPLE_POSITION: {
+ if (index >= ctx->DrawBuffer->Visual.samples) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetMultisamplefv(index)" );
+ return;
+ }
+
+ ctx->Driver.GetSamplePosition(ctx, ctx->DrawBuffer, index, val);
+
+ /* winsys FBOs are upside down */
+ if (_mesa_is_winsys_fbo(ctx->DrawBuffer))
+ val[1] = 1 - val[1];
+
+ return;
+ }
+
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );
+ return;
+ }
+}
+
+void GLAPIENTRY
+_mesa_SampleMaski(GLuint index, GLbitfield mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.ARB_texture_multisample) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMaski");
+ return;
+ }
+
+ if (index != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glSampleMaski(index)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleMaskValue = mask;
}
diff --git a/mesalib/src/mesa/main/multisample.h b/mesalib/src/mesa/main/multisample.h
index 30726c34c..9e6b8e0d3 100644
--- a/mesalib/src/mesa/main/multisample.h
+++ b/mesalib/src/mesa/main/multisample.h
@@ -38,4 +38,10 @@ extern void
_mesa_init_multisample(struct gl_context *ctx);
+extern void GLAPIENTRY
+_mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
+
+extern void GLAPIENTRY
+_mesa_SampleMaski(GLuint index, GLbitfield mask);
+
#endif
diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c
index 3fdb75323..3de736828 100644
--- a/mesalib/src/mesa/main/queryobj.c
+++ b/mesalib/src/mesa/main/queryobj.c
@@ -486,9 +486,14 @@ _mesa_QueryCounter(GLuint id, GLenum target)
q->Result = 0;
q->Ready = GL_FALSE;
- /* QueryCounter is implemented using EndQuery without BeginQuery
- * in drivers. This is actually Direct3D and Gallium convention. */
- ctx->Driver.EndQuery(ctx, q);
+ if (ctx->Driver.QueryCounter) {
+ ctx->Driver.QueryCounter(ctx, q);
+ } else {
+ /* QueryCounter is implemented using EndQuery without BeginQuery
+ * in drivers. This is actually Direct3D and Gallium convention.
+ */
+ ctx->Driver.EndQuery(ctx, q);
+ }
}
diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c
index a98a45c75..408125998 100644
--- a/mesalib/src/mesa/main/shared.c
+++ b/mesalib/src/mesa/main/shared.c
@@ -92,6 +92,8 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
/* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
static const GLenum targets[] = {
+ GL_TEXTURE_2D_MULTISAMPLE,
+ GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
GL_TEXTURE_CUBE_MAP_ARRAY,
GL_TEXTURE_BUFFER,
GL_TEXTURE_2D_ARRAY_EXT,
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index f0de0fb49..0dcf88ae4 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -661,7 +661,7 @@ _mesa_is_proxy_texture(GLenum target)
* NUM_TEXTURE_TARGETS should match number of terms below, except there's no
* proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
*/
- assert(NUM_TEXTURE_TARGETS == 8 + 2);
+ assert(NUM_TEXTURE_TARGETS == 10 + 2);
return (target == GL_PROXY_TEXTURE_1D ||
target == GL_PROXY_TEXTURE_2D ||
@@ -670,7 +670,9 @@ _mesa_is_proxy_texture(GLenum target)
target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
target == GL_PROXY_TEXTURE_2D_ARRAY_EXT ||
- target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY);
+ target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY ||
+ target == GL_PROXY_TEXTURE_2D_MULTISAMPLE ||
+ target == GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY);
}
@@ -711,6 +713,12 @@ _mesa_get_proxy_target(GLenum target)
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ return GL_PROXY_TEXTURE_2D_MULTISAMPLE;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY;
default:
_mesa_problem(NULL, "unexpected target in _mesa_get_proxy_target()");
return 0;
@@ -788,6 +796,18 @@ _mesa_select_tex_object(struct gl_context *ctx,
case GL_TEXTURE_EXTERNAL_OES:
return ctx->Extensions.OES_EGL_image_external
? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ return ctx->Extensions.ARB_texture_multisample
+ ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ return ctx->Extensions.ARB_texture_multisample
+ ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return ctx->Extensions.ARB_texture_multisample
+ ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return ctx->Extensions.ARB_texture_multisample
+ ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
default:
_mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
return NULL;
@@ -918,6 +938,16 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
return NULL;
texIndex = TEXTURE_CUBE_ARRAY_INDEX;
break;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ if (level > 0)
+ return 0;
+ texIndex = TEXTURE_2D_MULTISAMPLE_INDEX;
+ break;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ if (level > 0)
+ return 0;
+ texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX;
+ break;
default:
return NULL;
}
@@ -987,6 +1017,13 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
case GL_TEXTURE_BUFFER:
return ctx->API == API_OPENGL_CORE &&
ctx->Extensions.ARB_texture_buffer_object ? 1 : 0;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return _mesa_is_desktop_gl(ctx)
+ && ctx->Extensions.ARB_texture_multisample
+ ? 1 : 0;
case GL_TEXTURE_EXTERNAL_OES:
/* fall-through */
default:
@@ -1020,6 +1057,8 @@ _mesa_get_texture_dimensions(GLenum target)
case GL_TEXTURE_1D_ARRAY:
case GL_PROXY_TEXTURE_1D_ARRAY:
case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
return 2;
case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
@@ -1027,6 +1066,8 @@ _mesa_get_texture_dimensions(GLenum target)
case GL_PROXY_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
return 3;
case GL_TEXTURE_BUFFER:
/* fall-through */
@@ -1068,6 +1109,8 @@ _mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
break;
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return 1;
default:
assert(0);
@@ -1153,6 +1196,8 @@ clear_teximage_fields(struct gl_texture_image *img)
img->HeightLog2 = 0;
img->DepthLog2 = 0;
img->TexFormat = MESA_FORMAT_NONE;
+ img->NumSamples = 0;
+ img->FixedSampleLocations = GL_TRUE;
}
@@ -1196,6 +1241,9 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
img->WidthLog2 = _mesa_logbase2(img->Width2);
+ img->NumSamples = 0;
+ img->FixedSampleLocations = GL_TRUE;
+
switch(target) {
case GL_TEXTURE_1D:
case GL_TEXTURE_BUFFER:
@@ -1234,6 +1282,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
case GL_PROXY_TEXTURE_2D:
case GL_PROXY_TEXTURE_RECTANGLE:
case GL_PROXY_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
img->HeightLog2 = _mesa_logbase2(img->Height2);
if (depth == 0)
@@ -1246,6 +1296,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
case GL_PROXY_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
img->HeightLog2 = _mesa_logbase2(img->Height2);
img->Depth2 = depth; /* no border */
@@ -1317,6 +1369,8 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1399,6 +1453,8 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
case GL_TEXTURE_2D_ARRAY_EXT:
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -4102,3 +4158,183 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
texbufferrange(ctx, target, internalFormat, bufObj, offset, size);
}
+
+static GLboolean
+is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat)
+{
+ /* Everything that is allowed for renderbuffers,
+ * except for a base format of GL_STENCIL_INDEX.
+ */
+ GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
+ return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
+}
+
+/** GL_ARB_texture_multisample */
+static GLboolean
+check_multisample_target(GLuint dims, GLenum target)
+{
+ switch(target) {
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ return dims == 2;
+
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return dims == 3;
+
+ default:
+ return GL_FALSE;
+ }
+}
+
+static void
+teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedsamplelocations)
+{
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean sizeOK, dimensionsOK;
+ gl_format texFormat;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!(ctx->Extensions.ARB_texture_multisample
+ && _mesa_is_desktop_gl(ctx))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%uDMultisample", dims);
+ return;
+ }
+
+ if (!check_multisample_target(dims, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uDMultisample(target)", dims);
+ return;
+ }
+
+ /* check that the specified internalformat is color/depth/stencil-renderable;
+ * refer GL3.1 spec 4.4.4
+ */
+
+ if (!is_renderable_texture_format(ctx, internalformat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(internalformat=%s)",
+ dims,
+ _mesa_lookup_enum_by_nr(internalformat));
+ return;
+ }
+
+ if (_mesa_is_enum_format_integer(internalformat)) {
+ if (samples > ctx->Const.MaxIntegerSamples) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(samples>GL_MAX_INTEGER_SAMPLES)",
+ dims);
+ return;
+ }
+ }
+ else if (_mesa_is_depth_or_stencil_format(internalformat)) {
+ if (samples > ctx->Const.MaxDepthTextureSamples) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(samples>GL_MAX_DEPTH_TEXTURE_SAMPLES)",
+ dims);
+ return;
+ }
+ }
+ else {
+ if (samples > ctx->Const.MaxColorTextureSamples) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(samples>GL_MAX_COLOR_TEXTURE_SAMPLES)",
+ dims);
+ return;
+ }
+ }
+
+ /* TODO: should ask the driver for the exact limit for this internalformat
+ * once IDR's internalformat_query bits land
+ */
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ texImage = _mesa_get_tex_image(ctx, texObj, 0, 0);
+
+ if (texImage == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uDMultisample()", dims);
+ return;
+ }
+
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
+ internalformat, GL_NONE, GL_NONE);
+ assert(texFormat != MESA_FORMAT_NONE);
+
+ dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
+ width, height, depth, 0);
+
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
+ width, height, depth, 0);
+
+ if (_mesa_is_proxy_texture(target)) {
+ if (dimensionsOK && sizeOK) {
+ _mesa_init_teximage_fields(ctx, texImage,
+ width, height, depth, 0, internalformat, texFormat);
+ texImage->NumSamples = samples;
+ texImage->FixedSampleLocations = fixedsamplelocations;
+ }
+ else {
+ /* clear all image fields */
+ _mesa_init_teximage_fields(ctx, texImage,
+ 0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE);
+ }
+ }
+ else {
+ if (!dimensionsOK) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%uDMultisample(invalid width or height)", dims);
+ return;
+ }
+
+ if (!sizeOK) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glTexImage%uDMultisample(texture too large)", dims);
+ return;
+ }
+
+ ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
+
+ _mesa_init_teximage_fields(ctx, texImage,
+ width, height, depth, 0, internalformat, texFormat);
+
+ texImage->NumSamples = samples;
+ texImage->FixedSampleLocations = fixedsamplelocations;
+
+ if (width > 0 && height > 0 && depth > 0) {
+
+ if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1,
+ width, height, depth)) {
+ /* tidy up the texture image state. strictly speaking,
+ * we're allowed to just leave this in whatever state we
+ * like, but being tidy is good.
+ */
+ _mesa_init_teximage_fields(ctx, texImage,
+ 0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE);
+ }
+ }
+
+ _mesa_update_fbo_texture(ctx, texObj, 0, 0);
+ }
+}
+
+void GLAPIENTRY
+_mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLboolean fixedsamplelocations)
+{
+ teximagemultisample(2, target, samples, internalformat,
+ width, height, 1, fixedsamplelocations);
+}
+
+void GLAPIENTRY
+_mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ teximagemultisample(3, target, samples, internalformat,
+ width, height, depth, fixedsamplelocations);
+}
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 7124cac52..744c47a8a 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -294,6 +294,17 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
GLintptr offset, GLsizeiptr size);
+extern void GLAPIENTRY
+_mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLboolean fixedsamplelocations);
+
+extern void GLAPIENTRY
+_mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations);
+
/*@}*/
#ifdef __cplusplus
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index e99b0dc38..66377c8c0 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -109,7 +109,9 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
target == GL_TEXTURE_2D_ARRAY_EXT ||
target == GL_TEXTURE_EXTERNAL_OES ||
target == GL_TEXTURE_CUBE_MAP_ARRAY ||
- target == GL_TEXTURE_BUFFER);
+ target == GL_TEXTURE_BUFFER ||
+ target == GL_TEXTURE_2D_MULTISAMPLE ||
+ target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
memset(obj, 0, sizeof(*obj));
/* init the non-zero fields */
@@ -166,23 +168,39 @@ static void
finish_texture_init(struct gl_context *ctx, GLenum target,
struct gl_texture_object *obj)
{
+ GLenum filter = GL_LINEAR;
assert(obj->Target == 0);
- if (target == GL_TEXTURE_RECTANGLE_NV ||
- target == GL_TEXTURE_EXTERNAL_OES) {
- /* have to init wrap and filter state here - kind of klunky */
- obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
- obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
- obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
- obj->Sampler.MinFilter = GL_LINEAR;
- if (ctx->Driver.TexParameter) {
- static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
- static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_MIN_FILTER, fparam_filter);
- }
+ switch (target) {
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ filter = GL_NEAREST;
+ /* fallthrough */
+
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_EXTERNAL_OES:
+ /* have to init wrap and filter state here - kind of klunky */
+ obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
+ obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
+ obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
+ obj->Sampler.MinFilter = filter;
+ obj->Sampler.MagFilter = filter;
+ if (ctx->Driver.TexParameter) {
+ static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
+ const GLfloat fparam_filter[1] = {(GLfloat) filter};
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj,
+ GL_TEXTURE_MIN_FILTER, fparam_filter);
+ ctx->Driver.TexParameter(ctx, target, obj,
+ GL_TEXTURE_MAG_FILTER, fparam_filter);
+ }
+ break;
+
+ default:
+ /* nothing needs done */
+ break;
}
}
@@ -318,6 +336,8 @@ valid_texture_object(const struct gl_texture_object *tex)
case GL_TEXTURE_BUFFER:
case GL_TEXTURE_EXTERNAL_OES:
case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return GL_TRUE;
case 0x99:
_mesa_problem(NULL, "invalid reference to a deleted texture object");
@@ -517,6 +537,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
case GL_TEXTURE_RECTANGLE_NV:
case GL_TEXTURE_BUFFER:
case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
maxLevels = 1; /* no mipmapping */
break;
default:
@@ -585,7 +607,9 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
height = baseImage->Height2;
depth = baseImage->Depth2;
- /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL textures */
+ /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL,
+ * MULTISAMPLE and MULTISAMPLE_ARRAY textures
+ */
for (i = baseLevel + 1; i < maxLevels; i++) {
/* Compute the expected size of image at level[i] */
if (width > 1) {
@@ -763,7 +787,7 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
dims = 0;
target = GL_TEXTURE_BUFFER;
break;
- case TEXTURE_CUBE_ARRAY_INDEX:
+ case TEXTURE_CUBE_ARRAY_INDEX:
dims = 3;
target = GL_TEXTURE_CUBE_MAP_ARRAY;
break;
@@ -771,6 +795,14 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
dims = 2;
target = GL_TEXTURE_EXTERNAL_OES;
break;
+ case TEXTURE_2D_MULTISAMPLE_INDEX:
+ dims = 2;
+ target = GL_TEXTURE_2D_MULTISAMPLE;
+ break;
+ case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX:
+ dims = 3;
+ target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+ break;
default:
/* no-op */
return NULL;
@@ -960,6 +992,9 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
GLuint first;
GLint i;
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glGenTextures %d\n", n);
+
if (n < 0) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
return;
@@ -1069,6 +1104,9 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
GET_CURRENT_CONTEXT(ctx);
GLint i;
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glDeleteTextures %d\n", n);
+
FLUSH_VERTICES(ctx, 0); /* too complex */
if (!textures)
@@ -1156,6 +1194,12 @@ target_enum_to_index(struct gl_context *ctx, GLenum target)
? TEXTURE_EXTERNAL_INDEX : -1;
case GL_TEXTURE_CUBE_MAP_ARRAY:
return TEXTURE_CUBE_ARRAY_INDEX;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
+ ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
+ ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1;
default:
return -1;
}
@@ -1290,6 +1334,9 @@ _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
GET_CURRENT_CONTEXT(ctx);
GLint i;
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glPrioritizeTextures %d\n", n);
+
FLUSH_VERTICES(ctx, 0);
if (n < 0) {
@@ -1334,6 +1381,9 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
GLint i;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glAreTexturesResident %d\n", n);
+
if (n < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
return GL_FALSE;
@@ -1379,6 +1429,9 @@ _mesa_IsTexture( GLuint texture )
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glIsTexture %d\n", texture);
+
if (!texture)
return GL_FALSE;
@@ -1428,6 +1481,9 @@ _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
struct gl_texture_image *image;
GET_CURRENT_CONTEXT(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glInvalidateTexSubImage %d\n", texture);
+
t = invalidate_tex_image_error_check(ctx, texture, level,
"glInvalidateTexSubImage");
@@ -1494,6 +1550,7 @@ _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
break;
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
xBorder = image->Border;
yBorder = image->Border;
zBorder = 0;
@@ -1566,6 +1623,9 @@ _mesa_InvalidateTexImage(GLuint texture, GLint level)
{
GET_CURRENT_CONTEXT(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glInvalidateTexImage(%d, %d)\n", texture, level);
+
invalidate_tex_image_error_check(ctx, texture, level,
"glInvalidateTexImage");
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index bc66bb36d..120845b4a 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -966,6 +966,9 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
* "target may also be TEXTURE_BUFFER, indicating the texture buffer."
*/
return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return ctx->Extensions.ARB_texture_multisample;
default:
return GL_FALSE;
}
@@ -1105,6 +1108,19 @@ get_tex_level_parameter_image(struct gl_context *ctx,
*params = GL_NONE;
break;
+ /* GL_ARB_texture_multisample */
+ case GL_TEXTURE_SAMPLES:
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_pname;
+ *params = img->NumSamples;
+ break;
+
+ case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_pname;
+ *params = img->FixedSampleLocations;
+ break;
+
default:
goto invalid_pname;
}
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index 9e591d3b9..1bd9f911f 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -707,6 +707,8 @@ alloc_proxy_textures( struct gl_context *ctx )
* values!
*/
static const GLenum targets[] = {
+ GL_TEXTURE_2D_MULTISAMPLE,
+ GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
GL_TEXTURE_CUBE_MAP_ARRAY,
GL_TEXTURE_BUFFER,
GL_TEXTURE_2D_ARRAY_EXT,
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index 281d652a5..c5b44b7c1 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -50,6 +50,45 @@ check_for_ending(const char *string, const char *ending)
}
/**
+ * Returns the gl override data
+ *
+ * version > 0 indicates there is an override requested
+ * fwd_context is only valid if version > 0
+ */
+static void
+get_gl_override(int *version, GLboolean *fwd_context)
+{
+ const char *env_var = "MESA_GL_VERSION_OVERRIDE";
+ const char *version_str;
+ int major, minor, n;
+ static int override_version = -1;
+ static GLboolean fc_suffix = GL_FALSE;
+
+ if (override_version < 0) {
+ override_version = 0;
+
+ version_str = getenv(env_var);
+ if (version_str) {
+ fc_suffix = check_for_ending(version_str, "FC");
+
+ n = sscanf(version_str, "%u.%u", &major, &minor);
+ if (n != 2) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version_str);
+ override_version = 0;
+ } else {
+ override_version = major * 10 + minor;
+ if (override_version < 30 && fc_suffix) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version_str);
+ }
+ }
+ }
+ }
+
+ *version = override_version;
+ *fwd_context = fc_suffix;
+}
+
+/**
* Builds the MESA version string.
*/
static void
@@ -87,41 +126,42 @@ create_version_string(struct gl_context *ctx, const char *prefix)
void
_mesa_override_gl_version(struct gl_context *ctx)
{
- const char *env_var = "MESA_GL_VERSION_OVERRIDE";
- const char *version;
- int n;
- int major, minor;
- GLboolean fc_suffix;
+ int version;
+ GLboolean fwd_context;
- version = getenv(env_var);
- if (!version) {
- return;
- }
+ get_gl_override(&version, &fwd_context);
- fc_suffix = check_for_ending(version, "FC");
-
- n = sscanf(version, "%u.%u", &major, &minor);
- if (n != 2) {
- fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
- } else {
- ctx->Version = major * 10 + minor;
- if (ctx->Version < 30 && fc_suffix) {
- fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
+ if (version > 0) {
+ ctx->Version = version;
+ if (version >= 30 && fwd_context) {
+ ctx->API = API_OPENGL_CORE;
+ ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
+ } else if (version >= 31) {
+ ctx->API = API_OPENGL_CORE;
} else {
- if (ctx->Version >= 30 && fc_suffix) {
- ctx->API = API_OPENGL_CORE;
- ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
- } else if (ctx->Version >= 31) {
- ctx->API = API_OPENGL_CORE;
- } else {
- ctx->API = API_OPENGL_COMPAT;
- }
- create_version_string(ctx, "");
+ ctx->API = API_OPENGL_COMPAT;
}
+ create_version_string(ctx, "");
}
}
/**
+ * Returns the gl override value
+ *
+ * version > 0 indicates there is an override requested
+ */
+int
+_mesa_get_gl_version_override(void)
+{
+ int version;
+ GLboolean fwd_context;
+
+ get_gl_override(&version, &fwd_context);
+
+ return version;
+}
+
+/**
* Override the context's GLSL version if the environment variable
* MESA_GLSL_VERSION_OVERRIDE is set. Valid values for
* MESA_GLSL_VERSION_OVERRIDE are integers, such as "130".
diff --git a/mesalib/src/mesa/main/version.h b/mesalib/src/mesa/main/version.h
index 8167ed051..c1cb3177d 100644
--- a/mesalib/src/mesa/main/version.h
+++ b/mesalib/src/mesa/main/version.h
@@ -51,4 +51,7 @@ _mesa_override_gl_version(struct gl_context *ctx);
extern void
_mesa_override_glsl_version(struct gl_context *ctx);
+extern int
+_mesa_get_gl_version_override(void);
+
#endif /* VERSION_H */
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index ce409eca9..486cf4639 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -1478,6 +1478,13 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
assert(!"not supported");
break;
+ case ir_triop_lrp:
+ /* ir_triop_lrp operands are (x, y, a) while
+ * OPCODE_LRP operands are (a, y, x) to match ARB_fragment_program.
+ */
+ emit(ir, OPCODE_LRP, result_dst, op[2], op[1], op[0]);
+ break;
+
case ir_quadop_vector:
/* This operation should have already been handled.
*/
@@ -2038,6 +2045,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
ir->lod_info.grad.dPdy->accept(this);
dy = this->result;
break;
+ case ir_txf_ms:
+ assert(!"Unexpected ir_txf_ms opcode");
+ break;
}
const glsl_type *sampler_type = ir->sampler->type;
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 63b74285a..c41b5833e 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1942,6 +1942,10 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
}
break;
}
+ case ir_triop_lrp:
+ /* note: we have to reorder the three args here */
+ emit(ir, TGSI_OPCODE_LRP, result_dst, op[2], op[1], op[0]);
+ break;
case ir_unop_pack_snorm_2x16:
case ir_unop_pack_unorm_2x16:
case ir_unop_pack_half_2x16:
@@ -2742,6 +2746,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
offset = this->result;
}
break;
+ case ir_txf_ms:
+ assert(!"Unexpected ir_txf_ms opcode");
+ break;
}
if (ir->projector) {