From ffb53b4f0384fc811372644ce35471c0711eef9e Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Fri, 21 Dec 2012 21:33:37 +1300 Subject: [PATCH] glsl: add support for ARB_texture_multisample 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 [V2] Reviewed-by: Eric Anholt [V2] Reviewed-by: Paul Berry Reviewed-by: Ian Romanick --- src/glsl/builtin_types.h | 19 +++++++++++ .../profiles/ARB_texture_multisample.glsl | 18 +++++++++++ src/glsl/builtins/tools/generate_builtins.py | 1 + src/glsl/builtins/tools/texture_builtins.py | 28 ++++++++++++---- src/glsl/glcpp/glcpp-parse.y | 3 ++ src/glsl/glsl_lexer.ll | 15 +++++---- src/glsl/glsl_parser.yy | 11 +++++-- src/glsl/glsl_parser_extras.cpp | 1 + src/glsl/glsl_parser_extras.h | 2 ++ src/glsl/glsl_types.cpp | 17 ++++++++++ src/glsl/glsl_types.h | 5 ++- src/glsl/ir.cpp | 2 +- src/glsl/ir.h | 4 +++ src/glsl/ir_clone.cpp | 3 ++ src/glsl/ir_hv_accept.cpp | 5 +++ src/glsl/ir_print_visitor.cpp | 5 ++- src/glsl/ir_reader.cpp | 32 +++++++++++++------ src/glsl/ir_rvalue_visitor.cpp | 3 ++ src/glsl/opt_tree_grafting.cpp | 4 +++ src/glsl/standalone_scaffolding.cpp | 1 + 20 files changed, 153 insertions(+), 26 deletions(-) create mode 100644 src/glsl/builtins/profiles/ARB_texture_multisample.glsl diff --git a/src/glsl/builtin_types.h b/src/glsl/builtin_types.h index c78c2d27080..acd2d76d5a9 100644 --- a/src/glsl/builtin_types.h +++ b/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/src/glsl/builtins/profiles/ARB_texture_multisample.glsl b/src/glsl/builtins/profiles/ARB_texture_multisample.glsl new file mode 100644 index 00000000000..4fa67e95e30 --- /dev/null +++ b/src/glsl/builtins/profiles/ARB_texture_multisample.glsl @@ -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); diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py index 3db862e5f58..6da29c073e9 100755 --- a/src/glsl/builtins/tools/generate_builtins.py +++ b/src/glsl/builtins/tools/generate_builtins.py @@ -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; diff --git a/src/glsl/builtins/tools/texture_builtins.py b/src/glsl/builtins/tools/texture_builtins.py index 654eb06c888..f32391de9ea 100755 --- a/src/glsl/builtins/tools/texture_builtins.py +++ b/src/glsl/builtins/tools/texture_builtins.py @@ -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") diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index e927c7cb7cd..d6afe8814f2 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/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/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll index ddc9f80737d..008ef303d88 100644 --- a/src/glsl/glsl_lexer.ll +++ b/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/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index 154ce2d098b..f52ed9b0a94 100644 --- a/src/glsl/glsl_parser.yy +++ b/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 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/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index df1714850c4..9d7de3381fd 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/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/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 3ebc27e1a0d..1765cdf1611 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -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. */ diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index f78d2a6f8d8..a783dcc3b9c 100644 --- a/src/glsl/glsl_types.cpp +++ b/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; @@ -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); + } } diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 8cfd8dd021d..79304269dfc 100644 --- a/src/glsl/glsl_types.h +++ b/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/src/glsl/ir.cpp b/src/glsl/ir.cpp index 717d6f610ef..2eb3af6959c 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -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() { diff --git a/src/glsl/ir.h b/src/glsl/ir.h index d63dac100c7..393b4867368 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -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 0 1 ( ) ) * (txd 0 1 ( ) (dPdx dPdy)) * (txf 0 ) + * (txf_ms + * ) * (txs ) */ 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 */ diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index b94ff05df6c..4797451d7b2 100644 --- a/src/glsl/ir_clone.cpp +++ b/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/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp index 3ce8959245d..5fa75011ef4 100644 --- a/src/glsl/ir_hv_accept.cpp +++ b/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/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index acc92dbf165..3bdea9bbcbc 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/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/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 4dec4e87e58..22ce03b0d21 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -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 }; diff --git a/src/glsl/ir_rvalue_visitor.cpp b/src/glsl/ir_rvalue_visitor.cpp index b34a419e8e8..543c54496c9 100644 --- a/src/glsl/ir_rvalue_visitor.cpp +++ b/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/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp index 113abb7b043..985540196be 100644 --- a/src/glsl/opt_tree_grafting.cpp +++ b/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/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp index 0fb4f5b1656..8c0091e842f 100644 --- a/src/glsl/standalone_scaffolding.cpp +++ b/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; -- 2.30.2