summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/extensions.c1
-rw-r--r--src/mesa/main/mtypes.h14
-rw-r--r--src/mesa/program/ir_to_mesa.cpp5
-rw-r--r--src/mesa/program/prog_execute.c4
-rw-r--r--src/mesa/program/prog_execute.h1
-rw-r--r--src/mesa/program/prog_print.c5
-rw-r--r--src/mesa/state_tracker/st_extensions.c4
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c27
-rw-r--r--src/mesa/tnl/t_context.h2
-rw-r--r--src/mesa/tnl/t_draw.c19
-rw-r--r--src/mesa/tnl/t_vb_program.c7
11 files changed, 80 insertions, 9 deletions
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index c41ae4ad2d..24404993c6 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -380,6 +380,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
ctx->Extensions.ARB_depth_texture = GL_TRUE;
/*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
+ ctx->Extensions.ARB_draw_instanced = GL_TRUE;
ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
#if FEATURE_ARB_fragment_program
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index f76e1eb2ee..1522332e8a 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1748,11 +1748,24 @@ typedef enum
PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */
PROGRAM_ADDRESS, /**< machine->AddressReg */
PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */
+ PROGRAM_SYSTEM_VALUE,/**< InstanceId, PrimitiveID, etc. */
PROGRAM_UNDEFINED, /**< Invalid/TBD value */
PROGRAM_FILE_MAX
} gl_register_file;
+/**
+ * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be
+ * one of these values.
+ */
+typedef enum
+{
+ SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */
+ SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */
+ SYSTEM_VALUE_MAX /**< Number of values */
+} gl_system_value;
+
+
/** Vertex and fragment instructions */
struct prog_instruction;
struct gl_program_parameter_list;
@@ -1775,6 +1788,7 @@ struct gl_program
GLbitfield InputsRead; /**< Bitmask of which input regs are read */
GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
+ GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */
GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 0929b95950..786fdfbd23 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1462,6 +1462,7 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
case ir_var_in:
case ir_var_out:
case ir_var_inout:
+ case ir_var_system_value:
/* The linker assigns locations for varyings and attributes,
* including deprecated builtins (like gl_Color), user-assign
* generic attributes (glBindVertexLocation), and
@@ -1484,6 +1485,10 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
ir->var->type->gl_type,
ir->var->location - VERT_ATTRIB_GENERIC0);
}
+ } else if (ir->var->mode == ir_var_system_value) {
+ entry = new(mem_ctx) variable_storage(ir->var,
+ PROGRAM_SYSTEM_VALUE,
+ ir->var->location);
} else {
entry = new(mem_ctx) variable_storage(ir->var,
PROGRAM_OUTPUT,
diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c
index dd15e9a1cc..e7553c69db 100644
--- a/src/mesa/program/prog_execute.c
+++ b/src/mesa/program/prog_execute.c
@@ -159,6 +159,10 @@ get_src_register_pointer(const struct prog_src_register *source,
return ZeroVec;
return prog->Parameters->ParameterValues[reg];
+ case PROGRAM_SYSTEM_VALUE:
+ assert(reg < Elements(machine->SystemValues));
+ return machine->SystemValues[reg];
+
default:
_mesa_problem(NULL,
"Invalid src register file %d in get_src_register_pointer()",
diff --git a/src/mesa/program/prog_execute.h b/src/mesa/program/prog_execute.h
index cefd468c36..cdf37082a0 100644
--- a/src/mesa/program/prog_execute.h
+++ b/src/mesa/program/prog_execute.h
@@ -61,6 +61,7 @@ struct gl_program_machine
GLfloat (*EnvParams)[4]; /**< Vertex or Fragment env parameters */
GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
+ GLfloat SystemValues[SYSTEM_VALUE_MAX][4];
const GLubyte *Samplers; /** Array mapping sampler var to tex unit */
diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c
index abebf392c0..484596af76 100644
--- a/src/mesa/program/prog_print.c
+++ b/src/mesa/program/prog_print.c
@@ -72,6 +72,8 @@ _mesa_register_file_name(gl_register_file f)
return "ADDR";
case PROGRAM_SAMPLER:
return "SAMPLER";
+ case PROGRAM_SYSTEM_VALUE:
+ return "SYSVAL";
case PROGRAM_UNDEFINED:
return "UNDEFINED";
default:
@@ -310,6 +312,9 @@ reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
case PROGRAM_UNIFORM: /* extension */
sprintf(str, "uniform[%s%d]", addr, index);
break;
+ case PROGRAM_SYSTEM_VALUE:
+ sprintf(str, "sysvalue[%s%d]", addr, index);
+ break;
case PROGRAM_STATE_VAR:
{
struct gl_program_parameter *param
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index d240cab1a7..df4f5cf8b5 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -461,4 +461,8 @@ void st_init_extensions(struct st_context *st)
if (screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
ctx->Extensions.ARB_shader_stencil_export = GL_TRUE;
}
+
+ if (screen->get_param(screen, PIPE_CAP_INSTANCED_DRAWING)) {
+ ctx->Extensions.ARB_draw_instanced = GL_TRUE;
+ }
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index f848462310..42f1c2017f 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -72,6 +72,7 @@ struct st_translate {
struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
struct ureg_dst address[1];
struct ureg_src samplers[PIPE_MAX_SAMPLERS];
+ struct ureg_src systemValues[SYSTEM_VALUE_MAX];
/* Extra info for handling point size clamping in vertex shader */
struct ureg_dst pointSizeResult; /**< Actual point size output register */
@@ -104,6 +105,13 @@ struct st_translate {
};
+/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
+static unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = {
+ TGSI_SEMANTIC_FACE,
+ TGSI_SEMANTIC_INSTANCEID
+};
+
+
/**
* Make note of a branch to a label in the TGSI code.
* After we've emitted all instructions, we'll go over the list
@@ -245,6 +253,10 @@ src_register( struct st_translate *t,
case PROGRAM_ADDRESS:
return ureg_src(t->address[index]);
+ case PROGRAM_SYSTEM_VALUE:
+ assert(index < Elements(t->systemValues));
+ return t->systemValues[index];
+
default:
debug_assert( 0 );
return ureg_src_undef();
@@ -1089,6 +1101,21 @@ st_translate_mesa_program(
t->address[0] = ureg_DECL_address( ureg );
}
+ /* Declare misc input registers
+ */
+ {
+ GLbitfield sysInputs = program->SystemValuesRead;
+ unsigned numSys = 0;
+ for (i = 0; sysInputs; i++) {
+ if (sysInputs & (1 << i)) {
+ unsigned semName = mesa_sysval_to_semantic[i];
+ t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0);
+ numSys++;
+ sysInputs &= ~(1 << i);
+ }
+ }
+ }
+
if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) {
/* If temps are accessed with indirect addressing, declare temporaries
* in sequential order. Else, we declare them on demand elsewhere.
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index bc01646247..6a9444216c 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -527,6 +527,8 @@ typedef struct
GLubyte *block[VERT_ATTRIB_MAX];
GLuint nr_blocks;
+ GLuint CurInstance;
+
} TNLcontext;
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 30f1bf323c..bdb893eba2 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -453,6 +453,7 @@ void _tnl_draw_prims( struct gl_context *ctx,
*/
struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
GLuint nr_bo = 0;
+ GLuint inst;
for (i = 0; i < nr_prims;) {
GLuint this_nr_prims;
@@ -470,15 +471,19 @@ void _tnl_draw_prims( struct gl_context *ctx,
/* Binding inputs may imply mapping some vertex buffer objects.
* They will need to be unmapped below.
*/
- bind_prims(ctx, &prim[i], this_nr_prims);
- bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
- bo, &nr_bo);
- bind_indices(ctx, ib, bo, &nr_bo);
+ for (inst = 0; inst < prim[i].num_instances; inst++) {
- TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
+ bind_prims(ctx, &prim[i], this_nr_prims);
+ bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
+ bo, &nr_bo);
+ bind_indices(ctx, ib, bo, &nr_bo);
- unmap_vbos(ctx, bo, nr_bo);
- free_space(ctx);
+ tnl->CurInstance = inst;
+ TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
+
+ unmap_vbos(ctx, bo, nr_bo);
+ free_space(ctx);
+ }
i += this_nr_prims;
}
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 94372bbafb..f5d8f7477a 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -220,7 +220,8 @@ _tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *pr
* Initialize virtual machine state prior to executing vertex program.
*/
static void
-init_machine(struct gl_context *ctx, struct gl_program_machine *machine)
+init_machine(struct gl_context *ctx, struct gl_program_machine *machine,
+ GLuint instID)
{
/* Input registers get initialized from the current vertex attribs */
memcpy(machine->VertAttribs, ctx->Current.Attrib,
@@ -256,6 +257,8 @@ init_machine(struct gl_context *ctx, struct gl_program_machine *machine)
machine->FetchTexelDeriv = NULL; /* not used by vertex programs */
machine->Samplers = ctx->VertexProgram._Current->Base.SamplerUnits;
+
+ machine->SystemValues[SYSTEM_VALUE_INSTANCE_ID][0] = (GLfloat) instID;
}
@@ -341,7 +344,7 @@ run_vp( struct gl_context *ctx, struct tnl_pipeline_stage *stage )
for (i = 0; i < VB->Count; i++) {
GLuint attr;
- init_machine(ctx, machine);
+ init_machine(ctx, machine, tnl->CurInstance);
#if 0
printf("Input %d: %f, %f, %f, %f\n", i,