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

Maxence Le Doré maxence.ledore at gmail.com
Mon Nov 12 21:03:41 PST 2012


Here is a patch against master branch that takes a good way to implement
ARB_texture_gather over softpipe but I have the regret to announce that I
can't find what i'm doing wrong at a point :

At compilation time, more precisely glsl code compilation, a file
"builtin_function.cpp" is generated by python scripts, feed
.glsl/.frag/.vert./.ir files. I've done created the file that declares the
texture gather builtin functions and modified the python scripts that
generated IR for texture functions. But the buitin compiler complains about
wrong prototypes and leads to the production of a invalid
builtin_function.cpp file.

It's a little more irritating when I have the feeling to have exactly done
as Dave Airlied has done to implement ARB_texture_cube_map_array builtins
GLSL func few days ago. But that's wrong and I can figure out.

It sounds silly even to myself. I'm pretty sure it's a lack of attention
from me but i'm really blocked.

Some help are really welcome. I'm working heavly on over features but
texture gather support should be done before, this is why I try to
implement it.


The code ?


>From a17be83a8cbad91f1567c464a1a391fd345c8f93 Mon Sep 17 00:00:00 2001
From: Maxence Le Dore <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/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/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 +++
 28 files changed, 163 insertions(+), 8 deletions(-)

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/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);
     }

     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" };

 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/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
+/*@{*/

 /*
  * 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;
+
    /* 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;
    }

    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             */
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20121113/4b2823b2/attachment-0001.html>


More information about the mesa-dev mailing list