diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/main/extensions.c | 1 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 14 | ||||
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 5 | ||||
-rw-r--r-- | src/mesa/program/prog_execute.c | 4 | ||||
-rw-r--r-- | src/mesa/program/prog_execute.h | 1 | ||||
-rw-r--r-- | src/mesa/program/prog_print.c | 5 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_extensions.c | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 27 | ||||
-rw-r--r-- | src/mesa/tnl/t_context.h | 2 | ||||
-rw-r--r-- | src/mesa/tnl/t_draw.c | 19 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_program.c | 7 |
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, |