summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-12-08 18:25:38 -0700
committerBrian Paul <brianp@vmware.com>2010-12-08 18:25:38 -0700
commit7ce186358e881d1e30eda716a8dea73d2dab2ee9 (patch)
tree23d4f89f1ff2e5d69745f0423827f5c39b9218d5
parent379332f629153220614e651225b0521cd64c98b9 (diff)
glsl: add support for system values and GL_ARB_draw_instanced
-rw-r--r--src/glsl/glsl_parser_extras.cpp9
-rw-r--r--src/glsl/glsl_parser_extras.h2
-rw-r--r--src/glsl/ir.h1
-rw-r--r--src/glsl/ir_set_program_inouts.cpp9
-rw-r--r--src/glsl/ir_variable.cpp32
-rw-r--r--src/glsl/main.cpp1
6 files changed, 52 insertions, 2 deletions
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 302cfbc566..f7df3011ea 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -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);
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 98c4e70173..9b5f38a2bf 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -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;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 850033b185..8023a78dc2 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -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. */
};
diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp
index b3f1cc0d8b..31a122c6bb 100644
--- a/src/glsl/ir_set_program_inouts.cpp
+++ b/src/glsl/ir_set_program_inouts.cpp
@@ -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);
}
diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp
index 6b9b29458d..4d105400dd 100644
--- a/src/glsl/ir_variable.cpp
+++ b/src/glsl/ir_variable.cpp
@@ -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,
diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp
index 3302851264..36597d0bcd 100644
--- a/src/glsl/main.cpp
+++ b/src/glsl/main.cpp
@@ -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;