From d87bc015dc8b84257dc84e92cf4381c11a5086d3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 5 Dec 2010 13:32:59 -0700 Subject: gallium: added PIPE_CAP_INSTANCED_DRAWING --- src/gallium/docs/source/screen.rst | 1 + src/gallium/include/pipe/p_defines.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index e3ef49c862..a62520061e 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -36,6 +36,7 @@ The integer capabilities: bound. * ``OCCLUSION_QUERY``: Whether occlusion queries are available. * ``TIMER_QUERY``: Whether timer queries are available. +* ``INSTANCED_DRAWING``: indicates support for instanced drawing. * ``TEXTURE_SHADOW_MAP``: indicates whether the fragment shader hardware can do the depth texture / Z comparison operation in TEX instructions for shadow testing. diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index dacabed891..9f2b081e33 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -467,6 +467,7 @@ enum pipe_cap { PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER, PIPE_CAP_DEPTH_CLAMP, PIPE_CAP_SHADER_STENCIL_EXPORT, + PIPE_CAP_INSTANCED_DRAWING, }; /* Shader caps not specific to any single stage */ -- cgit v1.2.3 From 9cd277684db5a266b451a719a963556664838d6e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 5 Dec 2010 13:34:02 -0700 Subject: st/mesa: GL_ARB_draw_instanced depends on PIPE_CAP_INSTANCED_DRAWING --- src/mesa/state_tracker/st_extensions.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 930b60ade2..37a0aa2bc9 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -456,4 +456,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; + } } -- cgit v1.2.3 From 859f45a92197f310186924c47ef7b7d1c2bd7ec8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:19:14 -0700 Subject: tgsi: add support for system values to TGSI interpreter --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 19 ++++++++++++++++--- src/gallium/auxiliary/tgsi/tgsi_exec.h | 7 +++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 7892a67f04..35b2742351 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1038,7 +1038,6 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, break; case TGSI_FILE_INPUT: - case TGSI_FILE_SYSTEM_VALUE: for (i = 0; i < QUAD_SIZE; i++) { /* if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) { @@ -1053,6 +1052,15 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, } break; + case TGSI_FILE_SYSTEM_VALUE: + /* XXX no swizzling at this point. Will be needed if we put + * gl_FragCoord, for example, in a sys value register. + */ + for (i = 0; i < QUAD_SIZE; i++) { + chan->f[i] = mach->SystemValue[index->i[i]][0]; + } + break; + case TGSI_FILE_TEMPORARY: for (i = 0; i < QUAD_SIZE; i++) { assert(index->i[i] < TGSI_EXEC_NUM_TEMPS); @@ -1907,8 +1915,7 @@ exec_declaration(struct tgsi_exec_machine *mach, const struct tgsi_full_declaration *decl) { if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { - if (decl->Declaration.File == TGSI_FILE_INPUT || - decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) { + if (decl->Declaration.File == TGSI_FILE_INPUT) { uint first, last, mask; first = decl->Range.First; @@ -1921,6 +1928,7 @@ exec_declaration(struct tgsi_exec_machine *mach, * ureg code to emit the right UsageMask value (WRITEMASK_X). * Then, we could remove the tgsi_exec_machine::Face field. */ + /* XXX make FACE a system value */ if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) { uint i; @@ -1962,8 +1970,13 @@ exec_declaration(struct tgsi_exec_machine *mach, } } } + + if (decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) { + mach->SysSemanticToIndex[decl->Declaration.Semantic] = decl->Range.First; + } } + typedef void (* micro_op)(union tgsi_exec_channel *dst); static void diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index b5ebbfbfaa..6c204c7371 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -31,6 +31,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" #if defined __cplusplus extern "C" { @@ -181,6 +182,8 @@ struct tgsi_sampler /* The maximum total number of vertices */ #define TGSI_MAX_TOTAL_VERTICES (TGSI_MAX_PRIM_VERTICES * TGSI_MAX_PRIMITIVES * PIPE_MAX_ATTRIBS) +#define TGSI_MAX_MISC_INPUTS 8 + /** function call/activation record */ struct tgsi_call_record { @@ -228,6 +231,10 @@ struct tgsi_exec_machine struct tgsi_exec_vector Inputs[TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS]; struct tgsi_exec_vector Outputs[TGSI_MAX_TOTAL_VERTICES]; + /* System values */ + unsigned SysSemanticToIndex[TGSI_SEMANTIC_COUNT]; + float SystemValue[TGSI_MAX_MISC_INPUTS][4]; + struct tgsi_exec_vector *Addrs; struct tgsi_exec_vector *Predicates; -- cgit v1.2.3 From b550d8d76b42ef5ba5e8293dcc24220d5b683369 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:19:47 -0700 Subject: tgsi: new tgsi_shader_info fields for system values --- src/gallium/auxiliary/tgsi/tgsi_scan.c | 19 ++++++++++++++++++- src/gallium/auxiliary/tgsi/tgsi_scan.h | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index 6585da3e83..83c6ac75e5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -143,7 +143,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->file_count[file]++; info->file_max[file] = MAX2(info->file_max[file], (int)reg); - if (file == TGSI_FILE_INPUT || file == TGSI_FILE_SYSTEM_VALUE) { + if (file == TGSI_FILE_INPUT) { info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name; info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index; info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate; @@ -151,6 +151,23 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Declaration.CylindricalWrap; info->num_inputs++; } + else if (file == TGSI_FILE_SYSTEM_VALUE) { + unsigned index = fulldecl->Range.First; + unsigned semName = fulldecl->Semantic.Name; + + info->system_value_semantic_name[index] = semName; + info->num_system_values = MAX2(info->num_system_values, + index + 1); + + /* + info->system_value_semantic_name[info->num_system_values++] = + fulldecl->Semantic.Name; + */ + + if (fulldecl->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) { + info->uses_instanceid = TRUE; + } + } else if (file == TGSI_FILE_OUTPUT) { info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name; info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index; diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h index 104097fbc0..53ab3d509d 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h @@ -51,6 +51,9 @@ struct tgsi_shader_info ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; + ubyte num_system_values; + ubyte system_value_semantic_name[PIPE_MAX_SHADER_INPUTS]; + uint file_mask[TGSI_FILE_COUNT]; /**< bitmask of declared registers */ uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ int file_max[TGSI_FILE_COUNT]; /**< highest index of declared registers */ @@ -64,6 +67,7 @@ struct tgsi_shader_info boolean writes_stencil; /**< does fragment shader write stencil value? */ boolean writes_edgeflag; /**< vertex shader outputs edgeflag */ boolean uses_kill; /**< KIL or KILP instruction used? */ + boolean uses_instanceid; /** * Bitmask indicating which register files are accessed with -- cgit v1.2.3 From e8154eeae52c09783f537f5584e6fb57b3c5efb6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:20:05 -0700 Subject: tgsi/sse: add support for system values --- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 54 ++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 086d983a73..3f2cda860e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -163,6 +163,14 @@ get_immediate_base( void ) reg_DX ); } +static struct x86_reg +get_system_value_base( void ) +{ + return x86_make_disp( + get_machine_base(), + Offset(struct tgsi_exec_machine, SystemValue) ); +} + /** * Data access helpers. @@ -228,6 +236,16 @@ get_temp( (vec * 4 + chan) * 16 ); } +static struct x86_reg +get_system_value( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_system_value_base(), /* base */ + (vec * 4 + chan) * 4 ); /* byte offset from base */ +} + static struct x86_reg get_coef( unsigned vec, @@ -422,6 +440,30 @@ emit_tempf( get_temp( vec, chan ) ); } +/** + * Copy a system value to xmm register + * \param xmm the destination xmm register + * \param vec the source system value register + * \param chan src channel to fetch (X, Y, Z or W) + */ +static void +emit_system_value( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movss( + func, + make_xmm( xmm ), + get_system_value( vec, chan ) ); + sse_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + /** * Load an xmm register with an input attrib coefficient (a0, dadx or dady) * \param xmm the destination xmm register @@ -1281,8 +1323,15 @@ emit_fetch( swizzle ); break; - case TGSI_FILE_INPUT: case TGSI_FILE_SYSTEM_VALUE: + emit_system_value( + func, + xmm, + reg->Register.Index, + swizzle ); + break; + + case TGSI_FILE_INPUT: emit_inputf( func, xmm, @@ -2636,8 +2685,7 @@ emit_declaration( struct x86_function *func, struct tgsi_full_declaration *decl ) { - if( decl->Declaration.File == TGSI_FILE_INPUT || - decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) { + if( decl->Declaration.File == TGSI_FILE_INPUT ) { unsigned first, last, mask; unsigned i, j; -- cgit v1.2.3 From 975418a654e72d8338a9cf288d2d1f9429c226ae Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:20:44 -0700 Subject: tgsi/ppc: add case for system values and assert --- src/gallium/auxiliary/tgsi/tgsi_ppc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c index 3521847b61..537a0f6c5e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c @@ -294,7 +294,6 @@ emit_fetch(struct gen_context *gen, case TGSI_SWIZZLE_W: switch (reg->Register.File) { case TGSI_FILE_INPUT: - case TGSI_FILE_SYSTEM_VALUE: { int offset = (reg->Register.Index * 4 + swizzle) * 16; int offset_reg = emit_li_offset(gen, offset); @@ -302,6 +301,9 @@ emit_fetch(struct gen_context *gen, ppc_lvx(gen->f, dst_vec, gen->inputs_reg, offset_reg); } break; + case TGSI_FILE_SYSTEM_VALUE: + assert(!"unhandled system value in tgsi_ppc.c"); + break; case TGSI_FILE_TEMPORARY: if (is_ppc_vec_temporary(reg)) { /* use PPC vec register */ -- cgit v1.2.3 From c6d74bcbfcb54e0c03f4c3d7e82bc1267f36ffe4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:21:18 -0700 Subject: mesa: add PROGRAM_SYSTEM_VALUE and related tokens System values are shader inputs which don't necessarily change from vertex to vertex or fragment to fragment. gl_InstanceID and gl_FrontFacing are examples. --- src/mesa/main/mtypes.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 80c20e09d9..417f8df8e3 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1747,11 +1747,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; @@ -1774,6 +1787,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 */ -- cgit v1.2.3 From 379332f629153220614e651225b0521cd64c98b9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:24:48 -0700 Subject: mesa: program printing for PROGRAM_SYSTEM_VALUE --- src/mesa/program/prog_print.c | 5 +++++ 1 file changed, 5 insertions(+) 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 -- cgit v1.2.3 From 7ce186358e881d1e30eda716a8dea73d2dab2ee9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:25:38 -0700 Subject: glsl: add support for system values and GL_ARB_draw_instanced --- src/glsl/glsl_parser_extras.cpp | 9 +++++++++ src/glsl/glsl_parser_extras.h | 2 ++ src/glsl/ir.h | 1 + src/glsl/ir_set_program_inouts.cpp | 9 +++++++-- src/glsl/ir_variable.cpp | 32 ++++++++++++++++++++++++++++++++ src/glsl/main.cpp | 1 + 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; -- cgit v1.2.3 From 691048a22acf930e263711cf206e792a1b52f342 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 18:25:58 -0700 Subject: mesa: ir_to_mesa support for system values --- src/mesa/program/ir_to_mesa.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 8f75c82c3e..a5b17bb328 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -1460,6 +1460,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 @@ -1482,6 +1483,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, -- cgit v1.2.3 From 0be042cb4d256393750f7060d79bdaa2cd47d72e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 19:00:32 -0700 Subject: draw: setup instance ID for VS interpreter --- src/gallium/auxiliary/draw/draw_vs_exec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index dab3eb1ca8..08608b480e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -99,6 +99,12 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, constants, const_size); + if (shader->info.uses_instanceid) { + unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INSTANCEID]; + assert(i < Elements(machine->SystemValue)); + machine->SystemValue[i][0] = shader->draw->instance_id; + } + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); -- cgit v1.2.3 From 2d62fb6c3f7dd7261513253767cc63ff00fad9bb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 19:00:44 -0700 Subject: draw: setup instance ID for SSE generator --- src/gallium/auxiliary/draw/draw_vs_sse.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 0b0c6077c6..672efe25cc 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -71,6 +71,12 @@ vs_sse_prepare( struct draw_vertex_shader *base, struct tgsi_exec_machine *machine = shader->machine; machine->Samplers = draw->vs.samplers; + + if (base->info.uses_instanceid) { + unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INSTANCEID]; + assert(i < Elements(machine->SystemValue)); + machine->SystemValue[i][0] = base->draw->instance_id; + } } -- cgit v1.2.3 From 2b5e1e5287df5cae218b6f83d2638853d250aff9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 19:01:15 -0700 Subject: st/mesa: translate shader system inputs --- src/mesa/state_tracker/st_mesa_to_tgsi.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index c5c239b2c9..96c8aeb6e8 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(); @@ -1076,6 +1088,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. -- cgit v1.2.3 From 1d6f3543a063ab9e740fd0c149dcce26c282d773 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 19:02:14 -0700 Subject: gallivm/llvmpipe: implement system values and instanceID --- src/gallium/auxiliary/draw/draw_llvm.c | 21 ++++++-- src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 8 +++ src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 71 +++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_state_fs.c | 3 +- 4 files changed, 98 insertions(+), 5 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 2b5f01cda7..eb162fb0f6 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -340,6 +340,7 @@ generate_vs(struct draw_llvm *llvm, LLVMBuilderRef builder, LLVMValueRef (*outputs)[NUM_CHANNELS], const LLVMValueRef (*inputs)[NUM_CHANNELS], + LLVMValueRef system_values_array, LLVMValueRef context_ptr, struct lp_build_sampler_soa *draw_sampler) { @@ -371,6 +372,7 @@ generate_vs(struct draw_llvm *llvm, vs_type, NULL /*struct lp_build_mask_context *mask*/, consts_ptr, + system_values_array, NULL /*pos*/, inputs, outputs, @@ -1011,7 +1013,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) LLVMValueRef start, end, count, stride, step, io_itr; LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; LLVMValueRef instance_id; + LLVMValueRef system_values_array; struct draw_context *draw = llvm->draw; + const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; unsigned i, j; struct lp_build_context bld; struct lp_build_loop_state lp_loop; @@ -1070,6 +1074,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) lp_build_context_init(&bld, builder, lp_type_int(32)); + system_values_array = lp_build_system_values_array(builder, vs_info, + instance_id, NULL); + end = lp_build_add(&bld, start, count); step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); @@ -1126,6 +1133,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) builder, outputs, ptr_aos, + system_values_array, context_ptr, sampler); @@ -1156,8 +1164,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) /* store clipmask in vertex header and positions in data */ convert_to_aos(builder, io, outputs, clipmask, - draw->vs.vertex_shader->info.num_outputs, - max_vertices); + vs_info->num_outputs, max_vertices); } lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop); @@ -1207,7 +1214,9 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian LLVMValueRef fetch_elts, fetch_count, stride, step, io_itr; LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; LLVMValueRef instance_id; + LLVMValueRef system_values_array; struct draw_context *draw = llvm->draw; + const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; unsigned i, j; struct lp_build_context bld; struct lp_build_loop_state lp_loop; @@ -1268,6 +1277,10 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian lp_build_context_init(&bld, builder, lp_type_int(32)); + system_values_array = lp_build_system_values_array(builder, vs_info, + instance_id, NULL); + + step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); /* code generated texture sampling */ @@ -1332,6 +1345,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian builder, outputs, ptr_aos, + system_values_array, context_ptr, sampler); @@ -1365,8 +1379,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian * and transformed positions in data */ convert_to_aos(builder, io, outputs, clipmask, - draw->vs.vertex_shader->info.num_outputs, - max_vertices); + vs_info->num_outputs, max_vertices); } lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index a4d3b750c3..694818ccfb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -179,6 +179,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, + LLVMValueRef system_values_array, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[4], LLVMValueRef (*outputs)[4], @@ -198,4 +199,11 @@ lp_build_tgsi_aos(LLVMBuilderRef builder, const struct tgsi_shader_info *info); +LLVMValueRef +lp_build_system_values_array(LLVMBuilderRef builder, + const struct tgsi_shader_info *info, + LLVMValueRef instance_id, + LLVMValueRef facing); + + #endif /* LP_BLD_TGSI_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 7f0f058c22..3fdfac95a0 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -156,6 +156,8 @@ struct lp_build_tgsi_soa_context */ LLVMValueRef inputs_array; + LLVMValueRef system_values_array; + const struct tgsi_shader_info *info; /** bitmask indicating which register files are accessed indirectly */ unsigned indirect_files; @@ -732,6 +734,22 @@ emit_fetch( } break; + case TGSI_FILE_SYSTEM_VALUE: + assert(!reg->Register.Indirect); + { + LLVMValueRef index; /* index into the system value array */ + LLVMValueRef scalar, scalar_ptr; + + index = lp_build_const_int32(reg->Register.Index * 4 + swizzle); + + scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->system_values_array, + &index, 1, ""); + scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, ""); + + res = lp_build_broadcast_scalar(&bld->base, scalar); + } + break; + default: assert(0 && "invalid src register in emit_fetch()"); return bld->base.undef; @@ -2289,6 +2307,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, + LLVMValueRef system_values_array, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[NUM_CHANNELS], LLVMValueRef (*outputs)[NUM_CHANNELS], @@ -2375,6 +2394,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, } } + bld.system_values_array = system_values_array; + tgsi_parse_init( &parse, tokens ); while( !tgsi_parse_end_of_tokens( &parse ) ) { @@ -2476,3 +2497,53 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, FREE( bld.instructions ); } + +/** + * Build up the system values array out of individual values such as + * the instance ID, front-face, primitive ID, etc. The shader info is + * used to determine which system values are needed and where to put + * them in the system values array. + * + * XXX only instance ID is implemented at this time. + * + * The system values register file is similar to the constants buffer. + * Example declaration: + * DCL SV[0], INSTANCEID + * Example instruction: + * MOVE foo, SV[0].xxxx; + * + * \return LLVM float array (interpreted as float [][4]) + */ +LLVMValueRef +lp_build_system_values_array(LLVMBuilderRef builder, + const struct tgsi_shader_info *info, + LLVMValueRef instance_id, + LLVMValueRef facing) +{ + LLVMValueRef size = lp_build_const_int32(4 * info->num_system_values); + LLVMValueRef array = lp_build_array_alloca(builder, LLVMFloatType(), + size, "sysvals_array"); + unsigned i; + + for (i = 0; i < info->num_system_values; i++) { + LLVMValueRef index = lp_build_const_int32(i * 4); + LLVMValueRef ptr, value; + + switch (info->system_value_semantic_name[i]) { + case TGSI_SEMANTIC_INSTANCEID: + /* convert instance ID from int to float */ + value = LLVMBuildSIToFP(builder, instance_id, LLVMFloatType(), + "sysval_instanceid"); + break; + case TGSI_SEMANTIC_FACE: + /* fall-through */ + default: + assert(0 && "unexpected semantic in build_system_values_array()"); + } + + ptr = LLVMBuildGEP(builder, array, &index, 1, ""); + LLVMBuildStore(builder, value, ptr); + } + + return array; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 48971510f2..cd67d48861 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -334,7 +334,8 @@ generate_fs(struct lp_fragment_shader *shader, /* Build the actual shader */ lp_build_tgsi_soa(builder, tokens, type, &mask, - consts_ptr, interp->pos, interp->inputs, + consts_ptr, NULL, /* sys values array */ + interp->pos, interp->inputs, outputs, sampler, &shader->info.base); -- cgit v1.2.3 From cf2184f05717deb860aaaa031fbac48c89865ddd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 19:02:43 -0700 Subject: softpipe: enable instanced drawing cap --- src/gallium/drivers/softpipe/sp_screen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 5f171d314a..9b54babdfb 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -123,6 +123,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 0; case PIPE_CAP_SHADER_STENCIL_EXPORT: return 1; + case PIPE_CAP_INSTANCED_DRAWING: + return 1; default: return 0; } -- cgit v1.2.3 From dcb48e7eb41efb2d2ae12da0f59710334cf36796 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 8 Dec 2010 19:06:22 -0700 Subject: llvmpipe: enable instanced drawing cap --- src/gallium/drivers/llvmpipe/lp_screen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index ad0ea75b3a..43904343c3 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -164,6 +164,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTH_CLAMP: return 0; + case PIPE_CAP_INSTANCED_DRAWING: + return 1; default: return 0; } -- cgit v1.2.3 From 6a0d3b7696260f449a1d0c5222814568764e8110 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Dec 2010 09:29:00 -0700 Subject: mesa: implement system values in program interpreter --- src/mesa/program/prog_execute.c | 4 ++++ src/mesa/program/prog_execute.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c index 1d97a077f5..c20347fe67 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 */ -- cgit v1.2.3 From a63486ac680acc0bfb895037aca130a457caa01a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Dec 2010 09:29:13 -0700 Subject: tnl: implement instanced drawing --- src/mesa/tnl/t_context.h | 2 ++ src/mesa/tnl/t_draw.c | 19 ++++++++++++------- src/mesa/tnl/t_vb_program.c | 7 +++++-- 3 files changed, 19 insertions(+), 9 deletions(-) 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 76f8fde3f5..a1853689a4 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -218,7 +218,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, @@ -254,6 +255,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; } @@ -339,7 +342,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, -- cgit v1.2.3 From b7c38734c9d85f9dad1796d97690be2d9c55c397 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Dec 2010 09:29:41 -0700 Subject: mesa: enable GL_ARB_draw_instanced for software drivers --- src/mesa/main/extensions.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 3d5830c01c..a7bdfcc020 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -237,6 +237,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 -- cgit v1.2.3