[Mesa-dev] mesa : ARB_texture_gather implementation - WIP[PATCH1/1] but need advice !

Kenneth Graunke kenneth at whitecape.org
Tue Nov 13 14:53:50 PST 2012


On 11/13/2012 01:44 PM, Maxence Le Doré wrote:
> Oh sorry ! I simply forgot to add
> src/glsl/builtins/profiles/ARB_texture_gather.glsl to tracked files in
> my patch !
>
> Here comes the new one. I also add the forgotten xml api file.
>
> Thanks a lot Kenneth

Cool, thanks!

Could you please split this into several patches?  I would break it up 
like this:

1. mesa: Add basic plumbing for the ARB_texture_gather extension.

This would have the src/mesa/main and src/mapi/glapi changes (adding the 
extension enable bit, the XML, the glGet() changes, etc.)

2. glsl: Add support for the ARB_texture_gather extension.

This would have your src/glsl changes.

3. The Gallium changes (TGSI and st/mesa).

Also, when you send out those patches, could you please use 
git-send-email?  I wasn't able to apply your current patch cleanly. 
Using git-send-email allows us to easily save the email and apply it 
using 'git am'.  You can do that via:

git send-email --to mesa-dev at lists.freedesktop.org --annotate HEAD~3
(that sends the top three patches on your tree.  you can also do 
<sha>..<sha>, similar to git log.)

A few comments below:

>  From 9673f66ede72bf872824fd3430ae01b104b3d69f Mon Sep 17 00:00:00 2001
> From: Maxence Le Dore <maxence.ledore at gmail.com
> <mailto:maxence.ledore at gmail.com>>
> Date: Sat, 20 Oct 2012 02:31:41 +0200
> Subject: [PATCH] texture_gather
>
> ---
>   src/gallium/auxiliary/tgsi/tgsi_exec.c             |   74
> +++++++++++++++++++-
>   src/gallium/drivers/llvmpipe/lp_screen.c           |    3 +
>   src/gallium/drivers/softpipe/sp_screen.c           |    6 ++
>   src/gallium/drivers/softpipe/sp_tex_sample.c       |    8 +++
>   src/gallium/include/pipe/p_defines.h               |    5 +-
>   src/glsl/builtins/profiles/ARB_texture_gather.glsl |   26 +++++++
>   src/glsl/builtins/tools/generate_builtins.py       |    1 +
>   src/glsl/builtins/tools/texture_builtins.py        |   14 +++-
>   src/glsl/glcpp/glcpp-parse.y                       |    3 +
>   src/glsl/glsl_parser_extras.cpp                    |    1 +
>   src/glsl/glsl_parser_extras.h                      |    2 +
>   src/glsl/ir.cpp                                    |    2 +-
>   src/glsl/ir.h                                      |    4 +-
>   src/glsl/ir_clone.cpp                              |    1 +
>   src/glsl/ir_hv_accept.cpp                          |    1 +
>   src/glsl/ir_print_visitor.cpp                      |    3 +-
>   src/glsl/ir_rvalue_visitor.cpp                     |    1 +
>   src/glsl/opt_tree_grafting.cpp                     |    1 +
>   src/glsl/standalone_scaffolding.cpp                |    1 +
>   src/mapi/glapi/gen/ARB_texture_gather.xml          |   14 ++++
>   src/mapi/glapi/gen/gl_API.xml                      |    2 +-
>   src/mesa/main/config.h                             |    6 ++
>   src/mesa/main/extensions.c                         |    1 +
>   src/mesa/main/get_hash_params.py                   |    5 ++
>   src/mesa/main/mtypes.h                             |    6 ++
>   src/mesa/main/tests/enum_strings.cpp               |    3 +
>   src/mesa/program/ir_to_mesa.cpp                    |    2 +
>   src/mesa/program/prog_instruction.h                |    1 +
>   src/mesa/state_tracker/st_extensions.c             |    7 +-
>   src/mesa/state_tracker/st_glsl_to_tgsi.cpp         |    7 ++
>   30 files changed, 203 insertions(+), 8 deletions(-)
>   create mode 100644 src/glsl/builtins/profiles/ARB_texture_gather.glsl
>   create mode 100644 src/mapi/glapi/gen/ARB_texture_gather.xml
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c
> b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> index 1b7150b..0af1458 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> @@ -2119,6 +2119,78 @@ exec_txq(struct tgsi_exec_machine *mach,
>   }
>
>   static void
> +exec_txg(struct tgsi_exec_machine *mach,
> +     const struct tgsi_full_instruction *inst)
> +{
> +   struct tgsi_sampler *sampler;
> +   const uint unit = inst->Src[2].Register.Index;
> +   union tgsi_exec_channel r[4];
> +   union tgsi_exec_channel offset[3];
> +   uint chan;
> +   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
> +   int j;
> +   int8_t offsets[3];
> +
> +   if (inst->Texture.NumOffsets == 1) {
> +      union tgsi_exec_channel index;
> +      index.i[0] = index.i[1] = index.i[2] = index.i[3] =
> inst->TexOffsets[0].Index;
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleX, &index,
> &ZeroVec, &offset[0]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleY, &index,
> &ZeroVec, &offset[1]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleZ, &index,
> &ZeroVec, &offset[2]);
> +     offsets[0] = offset[0].i[0];
> +     offsets[1] = offset[1].i[0];
> +     offsets[2] = offset[2].i[0];
> +   } else
> +     offsets[0] = offsets[1] = offsets[2] = 0;
> +
> +   IFETCH(&r[3], 0, TGSI_CHAN_W);
> +
> +   switch(inst->Texture.Texture) {
> +   case TGSI_TEXTURE_2D_ARRAY:
> +   case TGSI_TEXTURE_CUBE_ARRAY:
> +      IFETCH(&r[2], 0, TGSI_CHAN_Z);
> +      /* fallthrough */
> +   case TGSI_TEXTURE_2D:
> +   case TGSI_TEXTURE_CUBE:
> +      IFETCH(&r[1], 0, TGSI_CHAN_Y);
> +      break;
> +   case TGSI_TEXTURE_1D:
> +   case TGSI_TEXTURE_3D:
> +   case TGSI_TEXTURE_SHADOW1D:
> +   case TGSI_TEXTURE_1D_ARRAY:
> +   case TGSI_TEXTURE_SHADOW2D:
> +   case TGSI_TEXTURE_SHADOWRECT:
> +   case TGSI_TEXTURE_SHADOW1D_ARRAY:
> +   case TGSI_TEXTURE_SHADOW2D_ARRAY:
> +      assert(0);
> +      /* fallthrough */
> +   default:
> +      assert(0);
> +      break;
> +   }
> +
> +   sampler = mach->Samplers[unit];
> +   sampler->get_texel(sampler, r[0].i, r[1].i, r[2].i, r[3].i,
> +              offsets, rgba);
> +
> +   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> +      r[0].f[j] = rgba[0][j];
> +      r[1].f[j] = rgba[1][j];
> +      r[2].f[j] = rgba[2][j];
> +      r[3].f[j] = rgba[3][j];
> +   }
> +
> +   for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
> +      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
> +         store_dest(mach, &r[chan], &inst->Dst[0], inst, chan,
> TGSI_EXEC_DATA_FLOAT);
> +      }
> +   }
> +}
> +
> +static void
>   exec_sample(struct tgsi_exec_machine *mach,
>               const struct tgsi_full_instruction *inst,
>               uint modifier)
> @@ -4215,7 +4287,7 @@ exec_instruction(
>         break;
>
>      case TGSI_OPCODE_GATHER4:
> -      assert(0);
> +      exec_txg(mach,inst);
>         break;
>
>      case TGSI_OPCODE_SVIEWINFO:
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c
> b/src/gallium/drivers/llvmpipe/lp_screen.c
> index e81c441..157e043 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -214,6 +214,9 @@ llvmpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>      case PIPE_CAP_TEXTURE_MULTISAMPLE:
>      case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
>      case PIPE_CAP_CUBE_MAP_ARRAY:
> +   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
> +   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
> +   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
>         return 0;
>      }
>      /* should only get here on unhandled cases */
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c
> b/src/gallium/drivers/softpipe/sp_screen.c
> index 3a38182..99f3344 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -171,6 +171,12 @@ softpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>      case PIPE_CAP_QUERY_TIMESTAMP:
>      case PIPE_CAP_CUBE_MAP_ARRAY:
>         return 1;
> +   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
> +      return -16;
> +   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
> +      return 15;
> +   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
> +      return 4;
>      }
>      /* should only get here on unhandled cases */
>      debug_printf("Unexpected PIPE_CAP %d query\n", param);
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c
> b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index 31eab39..3d53c10 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -1528,6 +1528,14 @@ img_filter_3d_linear(struct tgsi_sampler
> *tgsi_sampler,
>                                              tx12[c], tx13[c]);
>   }
>
> +img_gather_2d(struct tgsi_sampler *tgsi_sampler,
> +              float s,
> +              float t,
> +              unsigned level,
> +              enum tgsi_sampler_control control,
> +              float *rgba)
> +{
> +}
>
>   /* Calculate level of detail for every fragment.
>    * Note that lambda has already been biased by global LOD bias.
> diff --git a/src/gallium/include/pipe/p_defines.h
> b/src/gallium/include/pipe/p_defines.h
> index fa2fb07..4e99158 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -491,7 +491,10 @@ enum pipe_cap {
>      PIPE_CAP_QUERY_TIMESTAMP = 73,
>      PIPE_CAP_TEXTURE_MULTISAMPLE = 74,
>      PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT = 75,
> -   PIPE_CAP_CUBE_MAP_ARRAY = 76
> +   PIPE_CAP_CUBE_MAP_ARRAY = 76,
> +   PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET = 77,
> +   PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET = 78,
> +   PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS = 79
>   };
>
>   /**
> diff --git a/src/glsl/builtins/profiles/ARB_texture_gather.glsl
> b/src/glsl/builtins/profiles/ARB_texture_gather.glsl
> new file mode 100644
> index 0000000..c75a9bf
> --- /dev/null
> +++ b/src/glsl/builtins/profiles/ARB_texture_gather.glsl
> @@ -0,0 +1,26 @@
> +#version 130
> +#extension GL_ARB_texture_gather: enable
> +
> + vec4 textureGather( sampler2D sampler, vec2 coord);
> +ivec4 textureGather(isampler2D sampler, vec2 coord);
> +uvec4 textureGather(usampler2D sampler, vec2 coord);
> +
> + vec4 textureGather( sampler2DArray sampler, vec3 coord);
> +ivec4 textureGather(isampler2DArray sampler, vec3 coord);
> +uvec4 textureGather(usampler2DArray sampler, vec3 coord);
> +
> + vec4 textureGather( sampler2DCube sampler, vec3 coord);
> +ivec4 textureGather(isampler2DCube sampler, vec3 coord);
> +uvec4 textureGather(usampler2DCube sampler, vec3 coord);

This fails to compile because sampler2DCube is not a type :)  You want 
"samplerCube" here.

> + vec4 textureGather( samplerCubeArray sampler, vec4 coord);
> +ivec4 textureGather(isamplerCubeArray sampler, vec4 coord);
> +uvec4 textureGather(usamplerCubeArray sampler, vec4 coord);

This also fails to compile since the samplerCubeArray types aren't 
available unless you do:
#extension GL_ARB_texture_cube_map_array : enable

With both of those changes, your code compiles.

> + vec4 textureGatherOffset( sampler2D sampler, vec2 coord, ivec2 offset);
> +ivec4 textureGatherOffset(isampler2D sampler, vec2 coord, ivec2 offset);
> +uvec4 textureGatherOffset(usampler2D sampler, vec2 coord, ivec2 offset);
> +
> + vec4 textureGatherOffset( sampler2DArray sampler, vec3 coord, ivec2
> offset);
> +ivec4 textureGatherOffset(isampler2DArray sampler, vec3 coord, ivec2
> offset);
> +uvec4 textureGatherOffset(usampler2DArray sampler, vec3 coord, ivec2
> offset);
> \ No newline at end of file
> diff --git a/src/glsl/builtins/tools/generate_builtins.py
> b/src/glsl/builtins/tools/generate_builtins.py
> index 7eccb7d..2f024c2 100755
> --- a/src/glsl/builtins/tools/generate_builtins.py
> +++ b/src/glsl/builtins/tools/generate_builtins.py
> @@ -188,6 +188,7 @@ read_builtins(GLenum target, const char *protos,
> const char **functions, unsigne
>      st->OES_EGL_image_external_enable = true;
>      st->ARB_shader_bit_encoding_enable = true;
>      st->ARB_texture_cube_map_array_enable = true;
> +   st->ARB_texture_gather_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 654eb06..42b20d4 100755
> --- a/src/glsl/builtins/tools/texture_builtins.py
> +++ b/src/glsl/builtins/tools/texture_builtins.py
> @@ -105,7 +105,7 @@ def generate_sigs(g, tex_inst, sampler_type, variant
> = 0, unused_fields = 0):
>           else:
>               print "0",
>
> -    if tex_inst != "txf" and tex_inst != "txs":
> +    if tex_inst != "txf" and tex_inst != "txs" and tex_inst != "txg":
>           # Projective divisor
>           if variant & Proj:
>               print "(swiz " + "xyzw"[coord_dim + extra_dim-1] + "
> (var_ref P))",
> @@ -619,6 +619,18 @@ def generate_texture_functions(fs):
>       generate_sigs("", "txl", "2DShadow", Proj)
>       end_function(fs, "shadow2DProjLod")
>
> +    start_function("textureGather")
> +    generate_fiu_sigs("txg", "2D")
> +    generate_fiu_sigs("txg", "2DArray")
> +    generate_fiu_sigs("txg", "Cube")
> +    generate_fiu_sigs("txg", "CubeArray")
> +    end_function(fs, "textureGather")
> +
> +    start_function("textureGatherOffset")
> +    generate_fiu_sigs("txg", "2D", Offset)
> +    generate_fiu_sigs("txg", "2DArray", Offset)
> +    end_function(fs, "textureGatherOffset")
> +
>       sys.stdout = sys.__stdout__
>       return fs
>
> diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
> index 9628637..9eae568 100644
> --- a/src/glsl/glcpp/glcpp-parse.y
> +++ b/src/glsl/glcpp/glcpp-parse.y
> @@ -1190,6 +1190,9 @@ glcpp_parser_create (const struct gl_extensions
> *extensions, int api)
>
>          if (extensions->ARB_texture_cube_map_array)
>             add_builtin_define(parser, "GL_ARB_texture_cube_map_array", 1);
> +
> +       if (extensions->ARB_texture_cube_map_array)
> +          add_builtin_define(parser, "GL_ARB_texture_gather", 1);

Your check here is wrong: you want extensions->ARB_texture_gather.

>       }
>
>       language_version = 110;
> diff --git a/src/glsl/glsl_parser_extras.cpp
> b/src/glsl/glsl_parser_extras.cpp
> index f1fdd3a..ad99cdc 100644
> --- a/src/glsl/glsl_parser_extras.cpp
> +++ b/src/glsl/glsl_parser_extras.cpp
> @@ -290,6 +290,7 @@ static const _mesa_glsl_extension
> _mesa_glsl_supported_extensions[] = {
>      EXT(ARB_uniform_buffer_object,      true,  false, true,  true,
> false,     ARB_uniform_buffer_object),
>      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_texture_gather,             true,  false, true,  true,
> false,     ARB_texture_gather),
>   };
>
>   #undef EXT
> diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
> index 0b208f6..c058049 100644
> --- a/src/glsl/glsl_parser_extras.h
> +++ b/src/glsl/glsl_parser_extras.h
> @@ -183,6 +183,8 @@ struct _mesa_glsl_parse_state {
>      bool ARB_fragment_coord_conventions_warn;
>      bool ARB_texture_rectangle_enable;
>      bool ARB_texture_rectangle_warn;
> +   bool ARB_texture_gather_enable;
> +   bool ARB_texture_gather_warn;
>      bool EXT_texture_array_enable;
>      bool EXT_texture_array_warn;
>      bool ARB_shader_texture_lod_enable;
> diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
> index 7b0a487..a826395 100644
> --- a/src/glsl/ir.cpp
> +++ b/src/glsl/ir.cpp
> @@ -1282,7 +1282,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", "txs", "txg" };

Hmm.  I'm not a fan of the "txg" name, since at least in our hardware 
docs, sample_g means textureGrad() (an alias for 
sample_d...gradients/derivatives).  textureGather() is called "gather4" 
in our hardware.

I asked on IRC if people had ideas for a different name, and Dave 
suggested "ir_tg4".  Could we use that instead?

>   const char *ir_texture::opcode_string()
>   {
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
> index 89c516c..5d5b56d 100644
> --- a/src/glsl/ir.h
> +++ b/src/glsl/ir.h
> @@ -1334,7 +1334,8 @@ 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_txs        /**< Texture size */
> +   ir_txs,        /**< Texture size */
> +   ir_txg        /**< Texture gathering */
>   };
>
>
> @@ -1356,6 +1357,7 @@ enum ir_texture_opcode {
>    * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
>    * (txf <type> <sampler> <coordinate> 0       <lod>)
>    * (txs <type> <sampler> <lod>)
> + * (txg <type> <sampler> <coordinate>)
>    */
>   class ir_texture : public ir_rvalue {
>   public:
> diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
> index 4314efa..a6d8207 100644
> --- a/src/glsl/ir_clone.cpp
> +++ b/src/glsl/ir_clone.cpp
> @@ -246,6 +246,7 @@ ir_texture::clone(void *mem_ctx, struct hash_table
> *ht) const
>
>      switch (this->op) {
>      case ir_tex:
> +   case ir_txg:
>         break;
>      case ir_txb:
>         new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht);
> diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp
> index 3ce8959..155ed08 100644
> --- a/src/glsl/ir_hv_accept.cpp
> +++ b/src/glsl/ir_hv_accept.cpp
> @@ -213,6 +213,7 @@ ir_texture::accept(ir_hierarchical_visitor *v)
>
>      switch (this->op) {
>      case ir_tex:
> +   case ir_txg:
>         break;
>      case ir_txb:
>         s = this->lod_info.bias->accept(v);
> diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp
> index 8aa26e5..e54fef0 100644
> --- a/src/glsl/ir_print_visitor.cpp
> +++ b/src/glsl/ir_print_visitor.cpp
> @@ -259,7 +259,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_txs && ir->op != ir_txg) {
>         if (ir->projector)
>        ir->projector->accept(this);
>         else
> @@ -277,6 +277,7 @@ void ir_print_visitor::visit(ir_texture *ir)
>      switch (ir->op)
>      {
>      case ir_tex:
> +   case ir_txg:
>         break;
>      case ir_txb:
>         ir->lod_info.bias->accept(this);
> diff --git a/src/glsl/ir_rvalue_visitor.cpp b/src/glsl/ir_rvalue_visitor.cpp
> index b34a419..280ca74 100644
> --- a/src/glsl/ir_rvalue_visitor.cpp
> +++ b/src/glsl/ir_rvalue_visitor.cpp
> @@ -57,6 +57,7 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
>
>      switch (ir->op) {
>      case ir_tex:
> +   case ir_txg:
>         break;
>      case ir_txb:
>         handle_rvalue(&ir->lod_info.bias);
> diff --git a/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp
> index 25b18ea..c7f9e5b 100644
> --- a/src/glsl/opt_tree_grafting.cpp
> +++ b/src/glsl/opt_tree_grafting.cpp
> @@ -273,6 +273,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
>
>      switch (ir->op) {
>      case ir_tex:
> +   case ir_txg:
>         break;
>      case ir_txb:
>         if (do_graft(&ir->lod_info.bias))
> diff --git a/src/glsl/standalone_scaffolding.cpp
> b/src/glsl/standalone_scaffolding.cpp
> index 120ee95..e92dfd8 100644
> --- a/src/glsl/standalone_scaffolding.cpp
> +++ b/src/glsl/standalone_scaffolding.cpp
> @@ -82,6 +82,7 @@ void initialize_context_to_defaults(struct gl_context
> *ctx, gl_api api)
>      ctx->Extensions.ARB_shader_bit_encoding = true;
>      ctx->Extensions.OES_standard_derivatives = true;
>      ctx->Extensions.ARB_texture_cube_map_array = true;
> +   ctx->Extensions.ARB_texture_gather = true;
>
>      ctx->Const.GLSLVersion = 120;
>
> diff --git a/src/mapi/glapi/gen/ARB_texture_gather.xml
> b/src/mapi/glapi/gen/ARB_texture_gather.xml
> new file mode 100644
> index 0000000..cd331ac
> --- /dev/null
> +++ b/src/mapi/glapi/gen/ARB_texture_gather.xml
> @@ -0,0 +1,14 @@
> +<?xml version="1.0"?>
> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
> +
> +<OpenGLAPI>
> +
> +<category name="GL_ARB_texture_gather" number="72">
> +
> + <enum name="MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB" value="0x8E5E"/>
> + <enum name="MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB" value="0x8E5F"/>
> + <enum name="MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB" value="0x8F9F"/>
> +
> +</category>
> +
> +</OpenGLAPI>
> \ No newline at end of file
> diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
> index a47316a..a130b2c 100644
> --- a/src/mapi/glapi/gen/gl_API.xml
> +++ b/src/mapi/glapi/gen/gl_API.xml
> @@ -8187,7 +8187,7 @@
>
>   <!-- 70. GL_ARB_sample_shading -->
>   <xi:include href="ARB_texture_cube_map_array.xml"
> xmlns:xi="http://www.w3.org/2001/XInclude"/>
> -<!-- 72. GL_ARB_texture_gather -->
> +<xi:include href="ARB_texture_gather.xml"
> xmlns:xi="http://www.w3.org/2001/XInclude"/>
>   <!-- 73. GL_ARB_texture_query_lod -->
>
>   <!-- ARB extension number 74 is a WGL extension. -->
> diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
> index 99910d7..2a99514 100644
> --- a/src/mesa/main/config.h
> +++ b/src/mesa/main/config.h
> @@ -259,6 +259,12 @@
>   #define MAX_DEBUG_MESSAGE_LENGTH    4096
>   /*@}*/
>
> +/** For GL_ARB_texture_gather */
> +/*@{*/
> +#define MIN_PROGRAM_TEXTURE_GATHER_OFFSET     -16
> +#define MAX_PROGRAM_TEXTURE_GATHER_OFFSET      15
> +#define MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS  1
> +/*@{*/

These #defines should not exist.  There are no users of them, and these 
values don't match anything that I can find.

>   /*
>    * Color channel component order
> diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
> index d5a7886..8da6359 100644
> --- a/src/mesa/main/extensions.c
> +++ b/src/mesa/main/extensions.c
> @@ -135,6 +135,7 @@ static const struct extension extension_table[] = {
>      { "GL_ARB_texture_env_crossbar",
> o(ARB_texture_env_crossbar),                GLL,            2001 },
>      { "GL_ARB_texture_env_dot3",
> o(ARB_texture_env_dot3),                    GLL,            2001 },
>      { "GL_ARB_texture_float",
> o(ARB_texture_float),                       GL,             2004 },
> +   { "GL_ARB_texture_gather",
> o(ARB_texture_gather),                      GL,             2009 },
>      { "GL_ARB_texture_mirrored_repeat",
> o(dummy_true),                              GLL,            2001 },
>      { "GL_ARB_texture_multisample",
> o(ARB_texture_multisample),                 GL,             2009 },
>      { "GL_ARB_texture_non_power_of_two",
> o(ARB_texture_non_power_of_two),            GL,             2003 },
> diff --git a/src/mesa/main/get_hash_params.py
> b/src/mesa/main/get_hash_params.py
> index ac9c79c..9f33b83 100644
> --- a/src/mesa/main/get_hash_params.py
> +++ b/src/mesa/main/get_hash_params.py
> @@ -691,6 +691,11 @@ descriptor=[
>
>   # GL_ARB_texture_cube_map_array
>     [ "TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB", "LOC_CUSTOM, TYPE_INT,
> TEXTURE_CUBE_ARRAY_INDEX, extra_ARB_texture_cube_map_array" ],
> +
> +# GL_ARB_texture_gather
> +# [ "MIN_PROGRAM_TEXTURE_GATHER_OFFSET",
> "CONTEXT_INT(Const.MinProgramTextureGatherOffset),
> extra_ARB_texture_gather"],
> +# [ "MAX_PROGRAM_TEXTURE_GATHER_OFFSET",
> "CONTEXT_INT(Const.MaxProgramTextureGatherOffset),
> extra_ARB_texture_gather"],
> +# [ "MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS",
> "CONTEXT_INT(Const.MaxProgramTextureGatherComponents),
> extra_ARB_texture_gather"],
>   ]}
>
>   ]
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index da72da9..758cd18 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2889,6 +2889,11 @@ struct gl_constants
>      /** GL_EXT_gpu_shader4 */
>      GLint MinProgramTexelOffset, MaxProgramTexelOffset;
>
> +   /* GL_ARB_texture_gather */
> +   GLuint MinProgramTextureGatherOffest;
> +   GLuint MaxProgramTextureGatherOffest;
> +   GLuint MaxProgramTextureGatherComponents;
> +

You'll want to add code to initialize these to sane default values.  In 
context.c's _mesa_init_constants() function, look for 
ctx->Const.MinProgramTexelOffset and add similar code there.

According to the GL 4.2 spec, the minimum/maximum required values are -8 
and 7.  I would set the defaults to those---the minimum 
requirements---and let drivers that can provide more functionality raise 
the limits explicitly.

>      /* GL_ARB_robustness */
>      GLenum ResetStrategy;
>
> @@ -2981,6 +2986,7 @@ struct gl_extensions
>      GLboolean ARB_texture_env_crossbar;
>      GLboolean ARB_texture_env_dot3;
>      GLboolean ARB_texture_float;
> +   GLboolean ARB_texture_gather;
>      GLboolean ARB_texture_multisample;
>      GLboolean ARB_texture_non_power_of_two;
>      GLboolean ARB_texture_rg;
> diff --git a/src/mesa/main/tests/enum_strings.cpp
> b/src/mesa/main/tests/enum_strings.cpp
> index d473c30..18202a3 100644
> --- a/src/mesa/main/tests/enum_strings.cpp
> +++ b/src/mesa/main/tests/enum_strings.cpp
> @@ -1782,6 +1782,8 @@ const struct enum_info everything[] = {
>      { 0x8E4D, "GL_FIRST_VERTEX_CONVENTION" },
>      { 0x8E4E, "GL_LAST_VERTEX_CONVENTION" },
>      { 0x8E4F, "GL_PROVOKING_VERTEX" },
> +   { 0x8E5E, "GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET" },
> +   { 0x8E5F, "GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET" },
>      { 0x8F36, "GL_COPY_READ_BUFFER" },
>      { 0x8F37, "GL_COPY_WRITE_BUFFER" },
>      { 0x8F90, "GL_RED_SNORM" },
> @@ -1799,6 +1801,7 @@ const struct enum_info everything[] = {
>      { 0x8F9C, "GL_SIGNED_NORMALIZED" },
>      { 0x8F9D, "GL_PRIMITIVE_RESTART" },
>      { 0x8F9E, "GL_PRIMITIVE_RESTART_INDEX" },
> +   { 0x8F9F, "GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS" },
>      { 0x906F, "GL_RGB10_A2UI" },
>      { 0x9111, "GL_MAX_SERVER_WAIT_TIMEOUT" },
>      { 0x9112, "GL_OBJECT_TYPE" },
> diff --git a/src/mesa/program/ir_to_mesa.cpp
> b/src/mesa/program/ir_to_mesa.cpp
> index d5b9683..3cdc625 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -2023,6 +2023,8 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
>         ir->lod_info.grad.dPdy->accept(this);
>         dy = this->result;
>         break;
> +   case ir_txg:
> +      opcode = OPCODE_TXG;
>      }

ir_to_mesa is only used for old GPUs like i915, which will never support 
textureGather().  So I wouldn't add an opcode here.  Instead, I'd just:

assert(!"Invalid texture opcode.");

>      const glsl_type *sampler_type = ir->sampler->type;
> diff --git a/src/mesa/program/prog_instruction.h
> b/src/mesa/program/prog_instruction.h
> index a7bba75..3bbe756 100644
> --- a/src/mesa/program/prog_instruction.h
> +++ b/src/mesa/program/prog_instruction.h
> @@ -222,6 +222,7 @@ typedef enum prog_opcode {
>      OPCODE_TXL,       /*                    3       2         X   */
>      OPCODE_TXP,       /*            X                         X   */
>      OPCODE_TXP_NV,    /*                    3       X             */
> +   OPCODE_TXG,       /*                                      X   */
>      OPCODE_TRUNC,     /*                                      X   */
>      OPCODE_UP2H,      /*                            X             */
>      OPCODE_UP2US,     /*                            X             */

You don't need to add this opcode.  GLSL doesn't go through this code.

> diff --git a/src/mesa/state_tracker/st_extensions.c
> b/src/mesa/state_tracker/st_extensions.c
> index 7570d68..aa7ec5b 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -234,6 +234,10 @@ void st_init_limits(struct st_context *st)
>      c->MinProgramTexelOffset = screen->get_param(screen,
> PIPE_CAP_MIN_TEXEL_OFFSET);
>      c->MaxProgramTexelOffset = screen->get_param(screen,
> PIPE_CAP_MAX_TEXEL_OFFSET);
>
> +   c->MinProgramTextureGatherOffest = screen->get_param(screen,
> PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET);
> +   c->MaxProgramTextureGatherOffest = screen->get_param(screen,
> PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET);
> +   c->MaxProgramTextureGatherComponents = screen->get_param(screen,
> PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS);
> +
>      c->UniformBooleanTrue = ~0;
>
>      c->MaxTransformFeedbackBuffers =
> @@ -379,7 +383,8 @@ void st_init_extensions(struct st_context *st)
>         { o(MESA_texture_array),
> PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS         },
>
>         { o(OES_standard_derivatives),
> PIPE_CAP_SM3                              },
> -      { o(ARB_texture_cube_map_array),
> PIPE_CAP_CUBE_MAP_ARRAY                   }
> +      { o(ARB_texture_cube_map_array),
> PIPE_CAP_CUBE_MAP_ARRAY                   },
> +      { o(ARB_texture_gather),
> PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS    }
>      };
>
>      /* Required: render target and sampler support */
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index c030a6b..3aee6a5 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -2637,6 +2637,13 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
>        offset = this->result;
>         }
>         break;
> +   case ir_txg:
> +      opcode = TGSI_OPCODE_GATHER4;
> +      if (ir->offset) {
> +     ir->offset->accept(this);
> +     offset = this->result;
> +      }
> +      break;
>      }
>
>      if (ir->projector) {
> --
> 1.7.9.5

Thanks again for doing this!  I'm looking forward to seeing your next 
revision of the patch series.


More information about the mesa-dev mailing list