glsl: add support for system values and GL_ARB_draw_instanced
authorBrian Paul <brianp@vmware.com>
Thu, 9 Dec 2010 01:25:38 +0000 (18:25 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 9 Dec 2010 01:25:38 +0000 (18:25 -0700)
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_parser_extras.h
src/glsl/ir.h
src/glsl/ir_set_program_inouts.cpp
src/glsl/ir_variable.cpp
src/glsl/main.cpp

index 302cfbc5668e5917804e147d1e64f0be03e32ece..f7df3011eabbd64ac9b7452c42e19c88323a7ad7 100644 (file)
@@ -180,6 +180,15 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
         state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
         state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
       }
+   } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) {
+      /* This extension is only supported in vertex shaders.
+       */
+      if (state->target != vertex_shader) {
+        unsupported = true;
+      } else {
+        state->ARB_draw_instanced_enable = (ext_mode != extension_disable);
+        state->ARB_draw_instanced_warn = (ext_mode == extension_warn);
+      }
    } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
       state->ARB_explicit_attrib_location_enable =
         (ext_mode != extension_disable);
index 98c4e70173d74268ea8d95d3518ebdf5d4981cd8..9b5f38a2bf1bc48f504ed60b27ee7db3e84707fd 100644 (file)
@@ -124,6 +124,8 @@ struct _mesa_glsl_parse_state {
    /*@{*/
    unsigned ARB_draw_buffers_enable:1;
    unsigned ARB_draw_buffers_warn:1;
+   unsigned ARB_draw_instanced_enable:1;
+   unsigned ARB_draw_instanced_warn:1;
    unsigned ARB_explicit_attrib_location_enable:1;
    unsigned ARB_explicit_attrib_location_warn:1;
    unsigned ARB_fragment_coord_conventions_enable:1;
index 850033b185fca229165b89afb8abdab9e83bb904..8023a78dc2769119393895a7af11da0efa453de7 100644 (file)
@@ -224,6 +224,7 @@ enum ir_variable_mode {
    ir_var_in,
    ir_var_out,
    ir_var_inout,
+   ir_var_system_value, /**< Ex: front-face, instance-id, etc. */
    ir_var_temporary    /**< Temporary variable generated during compilation. */
 };
 
index b3f1cc0d8b53205972560c0b6bea5d5134d5bbea..31a122c6bb950984017a2c47ae14744bbe6fa3f0 100644 (file)
@@ -90,7 +90,10 @@ mark(struct gl_program *prog, ir_variable *var, int index)
 
    index *= element_size;
    for (int i = 0; i < element_size; i++) {
-      if (var->mode == ir_var_in)
+      if (var->mode == ir_var_system_value) {
+         prog->SystemValuesRead |= (1 << (var->location + index + i));
+      }
+      else if (var->mode == ir_var_in)
         prog->InputsRead |= BITFIELD64_BIT(var->location + index + i);
       else
         prog->OutputsWritten |= BITFIELD64_BIT(var->location + index + i);
@@ -139,7 +142,8 @@ ir_visitor_status
 ir_set_program_inouts_visitor::visit(ir_variable *ir)
 {
    if (ir->mode == ir_var_in ||
-       ir->mode == ir_var_out) {
+       ir->mode == ir_var_out ||
+       ir->mode == ir_var_system_value) {
       hash_table_insert(this->ht, ir, ir);
    }
 
@@ -163,5 +167,6 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog)
 
    prog->InputsRead = 0;
    prog->OutputsWritten = 0;
+   prog->SystemValuesRead = 0;
    visit_list_elements(&v, instructions);
 }
index 6b9b29458d082044f837743d8c36b6570cb09374..4d105400dd9382e95a06271bae7160f79276117f 100644 (file)
@@ -30,6 +30,11 @@ static void generate_ARB_draw_buffers_variables(exec_list *,
                                                struct _mesa_glsl_parse_state *,
                                                bool, _mesa_glsl_parser_targets);
 
+static void
+generate_ARB_draw_instanced_variables(exec_list *,
+                                      struct _mesa_glsl_parse_state *,
+                                      bool, _mesa_glsl_parser_targets);
+
 static ir_variable *
 add_variable(const char *name, enum ir_variable_mode mode, int slot,
             const glsl_type *type, exec_list *instructions,
@@ -41,6 +46,7 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot,
    case ir_var_auto:
    case ir_var_in:
    case ir_var_uniform:
+   case ir_var_system_value:
       var->read_only = true;
       break;
    case ir_var_inout:
@@ -324,8 +330,13 @@ initialize_vs_variables(exec_list *instructions,
       generate_130_vs_variables(instructions, state);
       break;
    }
+
+   if (state->ARB_draw_instanced_enable)
+      generate_ARB_draw_instanced_variables(instructions, state, false,
+                                            vertex_shader);
 }
 
+
 /* This function should only be called for ES, not desktop GL. */
 static void
 generate_100ES_fs_variables(exec_list *instructions,
@@ -422,6 +433,27 @@ generate_ARB_draw_buffers_variables(exec_list *instructions,
    }
 }
 
+
+static void
+generate_ARB_draw_instanced_variables(exec_list *instructions,
+                                      struct _mesa_glsl_parse_state *state,
+                                      bool warn,
+                                      _mesa_glsl_parser_targets target)
+{
+   /* gl_InstanceIDARB is only available in the vertex shader.
+    */
+   if (target == vertex_shader) {
+      ir_variable *const inst =
+         add_variable("gl_InstanceIDARB", ir_var_system_value,
+                      SYSTEM_VALUE_INSTANCE_ID,
+                      glsl_type::int_type, instructions, state->symbols);
+
+      if (warn)
+         inst->warn_extension = "GL_ARB_draw_instanced";
+   }
+}
+
+
 static void
 generate_ARB_shader_stencil_export_variables(exec_list *instructions,
                                             struct _mesa_glsl_parse_state *state,
index 33028512644c1eddfa30de353dc06d15a4248716..36597d0bcd0dbfb14af0dd5668b977ac85fd58be 100644 (file)
@@ -78,6 +78,7 @@ initialize_context(struct gl_context *ctx, gl_api api)
    ctx->API = api;
 
    ctx->Extensions.ARB_draw_buffers = GL_TRUE;
+   ctx->Extensions.ARB_draw_instanced = GL_TRUE;
    ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
    ctx->Extensions.EXT_texture_array = GL_TRUE;
    ctx->Extensions.NV_texture_rectangle = GL_TRUE;