glsl: add support for ARB_texture_multisample
authorChris Forbes <chrisf@ijw.co.nz>
Fri, 21 Dec 2012 08:33:37 +0000 (21:33 +1300)
committerChris Forbes <chrisf@ijw.co.nz>
Fri, 1 Mar 2013 22:33:54 +0000 (11:33 +1300)
V2: - emit `sample` parameter properly for multisample texelFetch()
    - fix spurious whitespace change
    - introduce a new opcode ir_txf_ms rather than overloading the
      existing ir_txf further. This makes doing the right thing in
      the driver somewhat simpler.

V3: - fix weird whitespace

V4: - don't forget to include the new opcode in tex_opcode_strs[]
      (thanks Kenneth for spotting this)

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
[V2] Reviewed-by: Eric Anholt <eric@anholt.net>
[V2] Reviewed-by: Paul Berry <stereotype441@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
20 files changed:
src/glsl/builtin_types.h
src/glsl/builtins/profiles/ARB_texture_multisample.glsl [new file with mode: 0644]
src/glsl/builtins/tools/generate_builtins.py
src/glsl/builtins/tools/texture_builtins.py
src/glsl/glcpp/glcpp-parse.y
src/glsl/glsl_lexer.ll
src/glsl/glsl_parser.yy
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_parser_extras.h
src/glsl/glsl_types.cpp
src/glsl/glsl_types.h
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_clone.cpp
src/glsl/ir_hv_accept.cpp
src/glsl/ir_print_visitor.cpp
src/glsl/ir_reader.cpp
src/glsl/ir_rvalue_visitor.cpp
src/glsl/opt_tree_grafting.cpp
src/glsl/standalone_scaffolding.cpp

index c78c2d27080b9768e4049a47eb12b0d573cd1d0f..acd2d76d5a929307397a243fb8a3ae6018b3defb 100644 (file)
@@ -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/src/glsl/builtins/profiles/ARB_texture_multisample.glsl b/src/glsl/builtins/profiles/ARB_texture_multisample.glsl
new file mode 100644 (file)
index 0000000..4fa67e9
--- /dev/null
@@ -0,0 +1,18 @@
+#version 130
+#extension GL_ARB_texture_multisample : enable
+
+ivec2 textureSize( sampler2DMS sampler);
+ivec2 textureSize(isampler2DMS sampler);
+ivec2 textureSize(usampler2DMS sampler);
+
+ivec3 textureSize( sampler2DMSArray sampler);
+ivec3 textureSize(isampler2DMSArray sampler);
+ivec3 textureSize(usampler2DMSArray sampler);
+
+ vec4 texelFetch( sampler2DMS sampler, ivec2 P, int sample);
+ivec4 texelFetch(isampler2DMS sampler, ivec2 P, int sample);
+uvec4 texelFetch(usampler2DMS sampler, ivec2 P, int sample);
+
+ vec4 texelFetch( sampler2DMSArray sampler, ivec3 P, int sample);
+ivec4 texelFetch(isampler2DMSArray sampler, ivec3 P, int sample);
+uvec4 texelFetch(usampler2DMSArray sampler, ivec3 P, int sample);
index 3db862e5f587925fbcd69bfc67c7ce035d2f57b2..6da29c073e90c6ac1a6be60c8333f42fb1c43200 100755 (executable)
@@ -190,6 +190,7 @@ read_builtins(GLenum target, const char *protos, const char **functions, unsigne
    st->ARB_shader_bit_encoding_enable = true;
    st->ARB_texture_cube_map_array_enable = true;
    st->ARB_shading_language_packing_enable = true;
+   st->ARB_texture_multisample_enable = true;
    _mesa_glsl_initialize_types(st);
 
    sh->ir = new(sh) exec_list;
index 654eb06c888c42a7d78b935b8d27deec5e138ea2..f32391de9ea46b47dfcd6fe9cf05fa803a4477b6 100755 (executable)
@@ -57,6 +57,12 @@ def get_txs_dim(sampler_type):
         return 2
     return get_coord_dim(sampler_type)
 
+def has_lod(sampler_type):
+    if 'Buffer' in sampler_type: return False
+    if 'Rect' in sampler_type: return False
+    if 'MS' in sampler_type: return False
+    return True
+
 def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
     coord_dim = get_coord_dim(sampler_type)
     extra_dim = get_extra_dim(sampler_type, variant & Proj, unused_fields)
@@ -74,11 +80,13 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
     print "     (parameters"
     print "       (declare (in) " + g + "sampler" + sampler_type + " sampler)",
     if tex_inst != "txs":
-        print "\n       (declare (in) " + vec_type("i" if tex_inst == "txf" else "", coord_dim + extra_dim) + " P)",
+        print "\n       (declare (in) " + vec_type("i" if tex_inst in ['txf','txf_ms'] else "", coord_dim + extra_dim) + " P)",
     if tex_inst == "txl":
         print "\n       (declare (in) float lod)",
-    elif ((tex_inst == "txf" or tex_inst == "txs") and "Buffer" not in sampler_type and "Rect" not in sampler_type):
+    elif tex_inst in ['txf', 'txs'] and has_lod(sampler_type):
         print "\n       (declare (in) int lod)",
+    elif tex_inst == "txf_ms":
+        print "\n       (declare (in) int sample)",
     elif tex_inst == "txd":
         grad_type = vec_type("", sampler_dim)
         print "\n       (declare (in) " + grad_type + " dPdx)",
@@ -100,12 +108,14 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
         else:
             print "(var_ref P)",
 
+    if tex_inst not in ['txf_ms', 'txs']:
+        # Coordinate offset
         if variant & Offset:
             print "(var_ref offset)",
         else:
             print "0",
 
-    if tex_inst != "txf" and tex_inst != "txs":
+    if tex_inst not in ['txf', 'txf_ms', 'txs']:
         # Projective divisor
         if variant & Proj:
             print "(swiz " + "xyzw"[coord_dim + extra_dim-1] + " (var_ref P))",
@@ -125,11 +135,13 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0):
     # Bias/explicit LOD/gradient:
     if tex_inst == "txb":
         print "(var_ref bias)",
-    elif tex_inst == "txs" or tex_inst == "txf":
-        if "Rect" not in sampler_type and "Buffer" not in sampler_type:
+    elif tex_inst in ['txs', 'txf', 'txf_ms']:
+        if has_lod(sampler_type):
             print "(var_ref lod)",
+        elif tex_inst == 'txf_ms':
+            print "(var_ref sample)",
         else:
-            print "(constant int (0))"
+            print "(constant int (0))",
     elif tex_inst == "txl":
         print "(var_ref lod)",
     elif tex_inst == "txd":
@@ -173,6 +185,8 @@ def generate_texture_functions(fs):
     generate_fiu_sigs("txs", "Buffer")
     generate_fiu_sigs("txs", "CubeArray")
     generate_sigs("", "txs", "CubeArrayShadow")
+    generate_fiu_sigs("txs", "2DMS")
+    generate_fiu_sigs("txs", "2DMSArray")
     end_function(fs, "textureSize")
 
     start_function("texture")
@@ -283,6 +297,8 @@ def generate_texture_functions(fs):
     generate_fiu_sigs("txf", "1DArray")
     generate_fiu_sigs("txf", "2DArray")
     generate_fiu_sigs("txf", "Buffer")
+    generate_fiu_sigs("txf_ms", "2DMS")
+    generate_fiu_sigs("txf_ms", "2DMSArray")
     end_function(fs, "texelFetch")
 
     start_function("texelFetchOffset")
index e927c7cb7cd75bea4a4c0b8fd336adb613d674bd..d6afe8814f21ae7ec1d1a997b92b120602ffcbc7 100644 (file)
@@ -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);
           }
        }
 
index ddc9f80737d0af16370819b909ec29afb212970f..008ef303d88042f7d2d1fe9b23080fdeb462a495 100644 (file)
@@ -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]* {
index 154ce2d098badc6f8c01537ed9004d584222b0a0..f52ed9b0a944b9f82337d015dfc6d4a730960a36 100644 (file)
@@ -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:
index df1714850c40d31947d50b48219359b79d125888..9d7de3381fd115a38a612ff42275bc561d31051f 100644 (file)
@@ -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
index 3ebc27e1a0dab330aedd5ac8066067d41e27fa98..1765cdf1611acdc9a6cc960158b0aca8820bec8d 100644 (file)
@@ -280,6 +280,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. */
index f78d2a6f8d8cae10552366309a5504f20e54916c..a783dcc3b9cebb4c10e9a1c0fbb52d7f72ac537c 100644 (file)
@@ -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;
@@ -344,6 +346,16 @@ glsl_type::generate_ARB_texture_cube_map_array_types(glsl_symbol_table *symtab,
                             warn, skip_1d);
 }
 
+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)
 {
@@ -413,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);
+   }
 }
 
 
index 8cfd8dd021d50eed5065e61f23a262df084d454f..79304269dfc8ae56f686f927f0070290929eae35 100644 (file)
@@ -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);
    /*@}*/
 
    /**
index 717d6f610ef79074ae48a3cc5f8322f292e96736..2eb3af6959c4a516dc3200c27a6943fe23212869 100644 (file)
@@ -1307,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()
 {
index d63dac100c711d48667f64cd9937fd6385cfcada..393b4867368f1ed06fd621e556b57dc4f50e5b7d 100644 (file)
@@ -1424,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 */
 };
 
@@ -1445,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 {
@@ -1511,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 */
index b94ff05df6c47df23e1f162e721285eee86c943b..4797451d7b29afbab17f1a2d7f5f0c058f557e00 100644 (file)
@@ -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);
index 3ce8959245db8fa3eaca638a52d8c799c21249cf..5fa75011ef414bd964e5f290550a7f1154bdebb3 100644 (file)
@@ -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)
index acc92dbf165967f2b7a458b3b9e05a95dc26010d..3bdea9bbcbc6e50500daaac01d85b6acc1206f77 100644 (file)
@@ -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);
index 4dec4e87e581cfb1d1f0ca4ed27b39a1815d097c..22ce03b0d21bbed313fc0942170059f0b7feab68 100644 (file)
@@ -911,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 */
 
@@ -918,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[] =
@@ -927,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)) {
@@ -966,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;
@@ -1020,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 };
index b34a419e8e818b202574876c0642a7dab968f08d..543c54496c9305c2aec49b70b9124985504789eb 100644 (file)
@@ -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);
index 113abb7b043021f5d76aad34b6c6e5b500166304..985540196be33d019637b76c45942ba3bfe2f55e 100644 (file)
@@ -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))
index 0fb4f5b1656df14f28186842d08e867a0b1283b7..8c0091e842f19db1e48797bfb5df557957eca15a 100644 (file)
@@ -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;