glsl: Add support for specifying the component in textureGather
authorChris Forbes <chrisf@ijw.co.nz>
Sat, 5 Oct 2013 05:26:56 +0000 (18:26 +1300)
committerChris Forbes <chrisf@ijw.co.nz>
Sat, 5 Oct 2013 22:12:29 +0000 (11:12 +1300)
ARB_gpu_shader5 introduces new variants of textureGather* which have an
explicit component selector, rather than relying purely on the sampler's
swizzle state.

This patch adds the GLSL plumbing for the extra parameter.

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/builtin_functions.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

index 40084f79f51cea1d851bb2392f3c389689d50e63..75c6da81e310a3d863244f75aa074cc637102021 100644 (file)
@@ -493,6 +493,7 @@ private:
 /** Flags to _texture() */
 #define TEX_PROJECT 1
 #define TEX_OFFSET  2
+#define TEX_COMPONENT 4
 
    ir_function_signature *_texture(ir_texture_opcode opcode,
                                    builtin_available_predicate avail,
@@ -3322,6 +3323,18 @@ builtin_builder::_texture(ir_texture_opcode opcode,
       tex->offset = var_ref(offset);
    }
 
+   if (opcode == ir_tg4) {
+      if (flags & TEX_COMPONENT) {
+         ir_variable *component =
+            new(mem_ctx) ir_variable(glsl_type::int_type, "comp", ir_var_const_in);
+         sig->parameters.push_tail(component);
+         tex->lod_info.component = var_ref(component);
+      }
+      else {
+         tex->lod_info.component = imm(0);
+      }
+   }
+
    /* The "bias" parameter comes /after/ the "offset" parameter, which is
     * inconsistent with both textureLodOffset and textureGradOffset.
     */
index 37f79f445885507ec075701d1ffa555da680254c..1a4a3a2e36b074f2bd496d1f4e5811216770cceb 100644 (file)
@@ -1586,7 +1586,7 @@ enum ir_texture_opcode {
  *      <type> <sampler> <coordinate>         <sample_index>)
  * (txs <type> <sampler> <lod>)
  * (lod <type> <sampler> <coordinate>)
- * (tg4 <type> <sampler> <coordinate> 0)
+ * (tg4 <type> <sampler> <coordinate> <offset> <component>)
  * (query_levels <type> <sampler>)
  */
 class ir_texture : public ir_rvalue {
@@ -1655,6 +1655,7 @@ public:
       ir_rvalue *lod;          /**< Floating point LOD */
       ir_rvalue *bias;         /**< Floating point LOD bias */
       ir_rvalue *sample_index;  /**< MSAA sample index */
+      ir_rvalue *component;     /**< Gather component selector */
       struct {
         ir_rvalue *dPdx;       /**< Partial derivative of coordinate wrt X */
         ir_rvalue *dPdy;       /**< Partial derivative of coordinate wrt Y */
index 8a40cb01b2fc5fd584b763c303049cd687b51dfd..dde22e018468f02ed9e19abda065991fe95b22ad 100644 (file)
@@ -248,7 +248,6 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
    switch (this->op) {
    case ir_tex:
    case ir_lod:
-   case ir_tg4:
    case ir_query_levels:
       break;
    case ir_txb:
@@ -266,6 +265,9 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
       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);
       break;
+   case ir_tg4:
+      new_tex->lod_info.component = this->lod_info.component->clone(mem_ctx, ht);
+      break;
    }
 
    return new_tex;
index 3aa008ac9829c595e56a57f7812ee0bd0e5cd71e..941b25e97c40534c06a55ca521ca6c5dc2bb28bc 100644 (file)
@@ -214,7 +214,6 @@ ir_texture::accept(ir_hierarchical_visitor *v)
    switch (this->op) {
    case ir_tex:
    case ir_lod:
-   case ir_tg4:
    case ir_query_levels:
       break;
    case ir_txb:
@@ -243,6 +242,11 @@ ir_texture::accept(ir_hierarchical_visitor *v)
       if (s != visit_continue)
         return (s == visit_continue_with_parent) ? visit_continue : s;
       break;
+   case ir_tg4:
+      s = this->lod_info.component->accept(v);
+      if (s != visit_continue)
+         return (s == visit_continue_with_parent) ? visit_continue : s;
+      break;
    }
 
    return (s == visit_stop) ? s : v->visit_leave(this);
index 531adc2997d82035df00aabc8608af17d950e7ca..f85e573c43e43e548f1d2cb8887110574a5d1c3c 100644 (file)
@@ -287,7 +287,6 @@ void ir_print_visitor::visit(ir_texture *ir)
    {
    case ir_tex:
    case ir_lod:
-   case ir_tg4:
    case ir_query_levels:
       break;
    case ir_txb:
@@ -308,6 +307,9 @@ void ir_print_visitor::visit(ir_texture *ir)
       ir->lod_info.grad.dPdy->accept(this);
       printf(")");
       break;
+   case ir_tg4:
+      ir->lod_info.component->accept(this);
+      break;
    };
    printf(")");
 }
index ea0c09aebebd0bdcd9bc42b57a1b24af730b66fb..00e2db9a3f06b842c0c7b779e407a278c87ad442 100644 (file)
@@ -934,6 +934,7 @@ ir_reader::read_texture(s_expression *expr)
    s_list *s_shadow = NULL;
    s_expression *s_lod = NULL;
    s_expression *s_sample_index = NULL;
+   s_expression *s_component = NULL;
 
    ir_texture_opcode op = ir_tex; /* silence warning */
 
@@ -948,7 +949,7 @@ ir_reader::read_texture(s_expression *expr)
    s_pattern txs_pattern[] =
       { "txs", s_type, s_sampler, s_lod };
    s_pattern tg4_pattern[] =
-      { "tg4", s_type, s_sampler, s_coord, s_offset };
+      { "tg4", s_type, s_sampler, s_coord, s_offset, s_component };
    s_pattern query_levels_pattern[] =
       { "query_levels", s_type, s_sampler };
    s_pattern other_pattern[] =
@@ -1089,6 +1090,13 @@ ir_reader::read_texture(s_expression *expr)
       }
       break;
    }
+   case ir_tg4:
+      tex->lod_info.component = read_rvalue(s_component);
+      if (tex->lod_info.component == NULL) {
+         ir_read_error(NULL, "when reading component in (tg4 ...)");
+         return NULL;
+      }
+      break;
    default:
       // tex and lod don't have any extra parameters.
       break;
index 2a79e4d8fb996631df3bbdbf98e58a08b28cc0ee..9d8ccd94a06bacce373290a2e404d54398adadbb 100644 (file)
@@ -57,7 +57,6 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
    switch (ir->op) {
    case ir_tex:
    case ir_lod:
-   case ir_tg4:
    case ir_query_levels:
       break;
    case ir_txb:
@@ -75,6 +74,9 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
       handle_rvalue(&ir->lod_info.grad.dPdx);
       handle_rvalue(&ir->lod_info.grad.dPdy);
       break;
+   case ir_tg4:
+      handle_rvalue(&ir->lod_info.component);
+      break;
    }
 
    return visit_continue;
index bbdc437598366d049a92cdeae8ac9abcf5728bbc..46c06e6c4a5fc91fe201d7f7ff3fac3b7be8ba04 100644 (file)
@@ -275,7 +275,6 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
    switch (ir->op) {
    case ir_tex:
    case ir_lod:
-   case ir_tg4:
    case ir_query_levels:
       break;
    case ir_txb:
@@ -297,6 +296,10 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
          do_graft(&ir->lod_info.grad.dPdy))
         return visit_stop;
       break;
+   case ir_tg4:
+      if (do_graft(&ir->lod_info.component))
+         return visit_stop;
+      break;
    }
 
    return visit_continue;