diff options
author | Bryan Cain <[email protected]> | 2013-02-15 10:02:18 -0600 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2013-10-17 08:35:42 +0100 |
commit | 9bfa475684fb20afacce01fa02b1a39bc3f23bdc (patch) | |
tree | 4531ac95142dbd2334b517f94a434b9ddbf794c9 /src | |
parent | 6b0df34ae5c0a8332559383c900241596eb2ac87 (diff) |
st/mesa, glsl_to_tgsi: add support for geometry shaders
v2 (Bryan Cain <[email protected]>): fix 2D array indexing order.
Signed-off-by: Dave Airlie <[email protected]>
Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 101 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 107 |
2 files changed, 163 insertions, 45 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 8d06ac6f7a7..3e11cce24f7 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -114,6 +114,8 @@ public: this->index2D = 0; this->type = type ? type->base_type : GLSL_TYPE_ERROR; this->reladdr = NULL; + this->reladdr2 = NULL; + this->has_index2 = false; } st_src_reg(gl_register_file file, int index, int type) @@ -125,6 +127,8 @@ public: this->swizzle = SWIZZLE_XYZW; this->negate = 0; this->reladdr = NULL; + this->reladdr2 = NULL; + this->has_index2 = false; } st_src_reg(gl_register_file file, int index, int type, int index2D) @@ -136,6 +140,8 @@ public: this->swizzle = SWIZZLE_XYZW; this->negate = 0; this->reladdr = NULL; + this->reladdr2 = NULL; + this->has_index2 = false; } st_src_reg() @@ -147,6 +153,8 @@ public: this->swizzle = 0; this->negate = 0; this->reladdr = NULL; + this->reladdr2 = NULL; + this->has_index2 = false; } explicit st_src_reg(st_dst_reg reg); @@ -159,10 +167,22 @@ public: int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ /** Register index should be offset by the integer in this reg. */ st_src_reg *reladdr; + st_src_reg *reladdr2; + bool has_index2; }; class st_dst_reg { public: + st_dst_reg(gl_register_file file, int writemask, int type, int index) + { + this->file = file; + this->index = index; + this->writemask = writemask; + this->cond_mask = COND_TR; + this->reladdr = NULL; + this->type = type; + } + st_dst_reg(gl_register_file file, int writemask, int type) { this->file = file; @@ -203,6 +223,8 @@ st_src_reg::st_src_reg(st_dst_reg reg) this->negate = 0; this->reladdr = reg.reladdr; this->index2D = 0; + this->reladdr2 = NULL; + this->has_index2 = false; } st_dst_reg::st_dst_reg(st_src_reg reg) @@ -449,7 +471,8 @@ static st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR); static st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR); -static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT); +static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 0); +static st_dst_reg address_reg2 = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 1); static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); @@ -515,9 +538,9 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, * sources into temps. */ num_reladdr += dst.reladdr != NULL; - num_reladdr += src0.reladdr != NULL; - num_reladdr += src1.reladdr != NULL; - num_reladdr += src2.reladdr != NULL; + num_reladdr += src0.reladdr != NULL || src0.reladdr2 != NULL; + num_reladdr += src1.reladdr != NULL || src1.reladdr2 != NULL; + num_reladdr += src2.reladdr != NULL || src2.reladdr2 != NULL; reladdr_to_temp(ir, &src2, &num_reladdr); reladdr_to_temp(ir, &src1, &num_reladdr); @@ -539,9 +562,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, inst->function = NULL; - if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL) - this->num_address_regs = 1; - /* Update indirect addressing status used by TGSI */ if (dst.reladdr) { switch(dst.file) { @@ -765,6 +785,10 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) op = TGSI_OPCODE_UARL; + assert(dst.file == PROGRAM_ADDRESS); + if (dst.index >= this->num_address_regs) + this->num_address_regs = dst.index + 1; + emit(NULL, op, dst, src0); } @@ -1328,10 +1352,11 @@ void glsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr) { - if (!reg->reladdr) + if (!reg->reladdr && !reg->reladdr2) return; - emit_arl(ir, address_reg, *reg->reladdr); + if (reg->reladdr) emit_arl(ir, address_reg, *reg->reladdr); + if (reg->reladdr2) emit_arl(ir, address_reg2, *reg->reladdr2); if (*num_reladdr != 1) { st_src_reg temp = get_temp(glsl_type::vec4_type); @@ -2098,14 +2123,26 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir) ir_constant *index; st_src_reg src; int element_size = type_size(ir->type); + bool is_2D_input; index = ir->array_index->constant_expression_value(); ir->array->accept(this); src = this->result; + is_2D_input = this->prog->Target == GL_GEOMETRY_PROGRAM_NV && + src.file == PROGRAM_INPUT && + ir->array->ir_type != ir_type_dereference_array; + + if (is_2D_input) + element_size = 1; + if (index) { - src.index += index->value.i[0] * element_size; + if (is_2D_input) { + src.index2D = index->value.i[0]; + src.has_index2 = true; + } else + src.index += index->value.i[0] * element_size; } else { /* Variable index array dereference. It eats the "vec4" of the * base of the array and an index that offsets the TGSI register @@ -2128,7 +2165,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir) /* If there was already a relative address register involved, add the * new and the old together to get the new offset. */ - if (src.reladdr != NULL) { + if (!is_2D_input && src.reladdr != NULL) { st_src_reg accum_reg = get_temp(native_integers ? glsl_type::int_type : glsl_type::float_type); @@ -2138,8 +2175,15 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir) index_reg = accum_reg; } - src.reladdr = ralloc(mem_ctx, st_src_reg); - memcpy(src.reladdr, &index_reg, sizeof(index_reg)); + if (is_2D_input) { + src.reladdr2 = ralloc(mem_ctx, st_src_reg); + memcpy(src.reladdr2, &index_reg, sizeof(index_reg)); + src.index2D = 0; + src.has_index2 = true; + } else { + src.reladdr = ralloc(mem_ctx, st_src_reg); + memcpy(src.reladdr, &index_reg, sizeof(index_reg)); + } } /* If the type is smaller than a vec4, replicate the last channel out. */ @@ -3018,16 +3062,19 @@ glsl_to_tgsi_visitor::visit(ir_if *ir) if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF); } + void glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir) { - assert(!"Geometry shaders not supported."); + assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV); + emit(ir, TGSI_OPCODE_EMIT); } void glsl_to_tgsi_visitor::visit(ir_end_primitive *ir) { - assert(!"Geometry shaders not supported."); + assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV); + emit(ir, TGSI_OPCODE_ENDPRIM); } glsl_to_tgsi_visitor::glsl_to_tgsi_visitor() @@ -3440,7 +3487,8 @@ glsl_to_tgsi_visitor::copy_propagate(void) int acp_base = inst->src[r].index * 4; if (inst->src[r].file != PROGRAM_TEMPORARY || - inst->src[r].reladdr) + inst->src[r].reladdr || + inst->src[r].reladdr2) continue; /* See if we can find entries in the ACP consisting of MOVs @@ -3475,6 +3523,8 @@ glsl_to_tgsi_visitor::copy_propagate(void) */ inst->src[r].file = first->src[0].file; inst->src[r].index = first->src[0].index; + inst->src[r].index2D = first->src[0].index2D; + inst->src[r].has_index2 = first->src[0].has_index2; int swizzle = 0; for (int i = 0; i < 4; i++) { @@ -3579,6 +3629,7 @@ glsl_to_tgsi_visitor::copy_propagate(void) !inst->dst.reladdr && !inst->saturate && !inst->src[0].reladdr && + !inst->src[0].reladdr2 && !inst->src[0].negate) { for (int i = 0; i < 4; i++) { if (inst->dst.writemask & (1 << i)) { @@ -4078,7 +4129,7 @@ struct st_translate { struct ureg_src *immediates; struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; - struct ureg_dst address[1]; + struct ureg_dst address[2]; struct ureg_src samplers[PIPE_MAX_SAMPLERS]; struct ureg_src systemValues[SYSTEM_VALUE_MAX]; @@ -4355,6 +4406,15 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg) { struct ureg_src src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D); + if (t->procType == TGSI_PROCESSOR_GEOMETRY && src_reg->has_index2) { + src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D); + if (src_reg->reladdr2) + src = ureg_src_dimension_indirect(src, ureg_src(t->address[1]), + src_reg->index2D); + else + src = ureg_src_dimension(src, src_reg->index2D); + } + src = ureg_swizzle(src, GET_SWZ(src_reg->swizzle, 0) & 0x3, GET_SWZ(src_reg->swizzle, 1) & 0x3, @@ -4844,8 +4904,10 @@ st_translate_program( /* Declare address register. */ if (program->num_address_regs > 0) { - assert(program->num_address_regs == 1); + assert(program->num_address_regs <= 2); t->address[0] = ureg_DECL_address(ureg); + if (program->num_address_regs == 2) + t->address[1] = ureg_DECL_address(ureg); } /* Declare misc input registers @@ -5166,6 +5228,9 @@ get_mesa_program(struct gl_context *ctx, case GL_GEOMETRY_SHADER: stgp = (struct st_geometry_program *)prog; stgp->glsl_to_tgsi = v; + stgp->Base.InputType = shader_program->Geom.InputType; + stgp->Base.OutputType = shader_program->Geom.OutputType; + stgp->Base.VerticesOut = shader_program->Geom.VerticesOut; break; default: assert(!"should not be reached"); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 211b879e0d8..925ea80403f 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -828,7 +828,6 @@ st_translate_geometry_program(struct st_context *st, GLuint attr; GLbitfield64 inputsRead; GLuint vslot = 0; - GLuint num_generic = 0; uint gs_num_inputs = 0; uint gs_builtin_inputs = 0; @@ -848,7 +847,9 @@ st_translate_geometry_program(struct st_context *st, if (!gpv) return NULL; - _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT); + if (!stgp->glsl_to_tgsi) { + _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT); + } ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY ); if (ureg == NULL) { @@ -910,6 +911,18 @@ st_translate_geometry_program(struct st_context *st, stgp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG; stgp->input_semantic_index[slot] = 0; break; + case VARYING_SLOT_CLIP_VERTEX: + stgp->input_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX; + stgp->input_semantic_index[slot] = 0; + break; + case VARYING_SLOT_CLIP_DIST0: + stgp->input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; + stgp->input_semantic_index[slot] = 0; + break; + case VARYING_SLOT_CLIP_DIST1: + stgp->input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; + stgp->input_semantic_index[slot] = 1; + break; case VARYING_SLOT_TEX0: case VARYING_SLOT_TEX1: case VARYING_SLOT_TEX2: @@ -919,13 +932,17 @@ st_translate_geometry_program(struct st_context *st, case VARYING_SLOT_TEX6: case VARYING_SLOT_TEX7: stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stgp->input_semantic_index[slot] = num_generic++; + stgp->input_semantic_index[slot] = (attr - VARYING_SLOT_TEX0); break; case VARYING_SLOT_VAR0: - /* fall-through */ default: + assert(attr >= VARYING_SLOT_VAR0 && attr < VARYING_SLOT_MAX); stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stgp->input_semantic_index[slot] = num_generic++; + stgp->input_semantic_index[slot] = (VARYING_SLOT_VAR0 - + VARYING_SLOT_TEX0 + + attr - + VARYING_SLOT_VAR0); + break; } } } @@ -936,7 +953,6 @@ st_translate_geometry_program(struct st_context *st, gs_output_semantic_index[i] = 0; } - num_generic = 0; /* * Determine number of outputs, the (default) output register * mapping and the semantic information for each output. @@ -979,6 +995,18 @@ st_translate_geometry_program(struct st_context *st, gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; gs_output_semantic_index[slot] = 0; break; + case VARYING_SLOT_CLIP_VERTEX: + gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX; + gs_output_semantic_index[slot] = 0; + break; + case VARYING_SLOT_CLIP_DIST0: + gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; + gs_output_semantic_index[slot] = 0; + break; + case VARYING_SLOT_CLIP_DIST1: + gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; + gs_output_semantic_index[slot] = 1; + break; case VARYING_SLOT_TEX0: case VARYING_SLOT_TEX1: case VARYING_SLOT_TEX2: @@ -987,14 +1015,18 @@ st_translate_geometry_program(struct st_context *st, case VARYING_SLOT_TEX5: case VARYING_SLOT_TEX6: case VARYING_SLOT_TEX7: - /* fall-through */ + gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + gs_output_semantic_index[slot] = (attr - VARYING_SLOT_TEX0); + break; case VARYING_SLOT_VAR0: - /* fall-through */ default: assert(slot < Elements(gs_output_semantic_name)); - /* use default semantic info */ + assert(attr >= VARYING_SLOT_VAR0); gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - gs_output_semantic_index[slot] = num_generic++; + gs_output_semantic_index[slot] = (VARYING_SLOT_VAR0 - + VARYING_SLOT_TEX0 + + attr - + VARYING_SLOT_VAR0); } } } @@ -1038,23 +1070,44 @@ st_translate_geometry_program(struct st_context *st, ureg_property_gs_output_prim(ureg, stgp->Base.OutputType); ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut); - st_translate_mesa_program(st->ctx, - TGSI_PROCESSOR_GEOMETRY, - ureg, - &stgp->Base.Base, - /* inputs */ - gs_num_inputs, - inputMapping, - stgp->input_semantic_name, - stgp->input_semantic_index, - NULL, - /* outputs */ - gs_num_outputs, - outputMapping, - gs_output_semantic_name, - gs_output_semantic_index, - FALSE, - FALSE); + if (stgp->glsl_to_tgsi) + st_translate_program(st->ctx, + TGSI_PROCESSOR_GEOMETRY, + ureg, + stgp->glsl_to_tgsi, + &stgp->Base.Base, + /* inputs */ + gs_num_inputs, + inputMapping, + stgp->input_semantic_name, + stgp->input_semantic_index, + NULL, + NULL, + /* outputs */ + gs_num_outputs, + outputMapping, + gs_output_semantic_name, + gs_output_semantic_index, + FALSE, + FALSE); + else + st_translate_mesa_program(st->ctx, + TGSI_PROCESSOR_GEOMETRY, + ureg, + &stgp->Base.Base, + /* inputs */ + gs_num_inputs, + inputMapping, + stgp->input_semantic_name, + stgp->input_semantic_index, + NULL, + /* outputs */ + gs_num_outputs, + outputMapping, + gs_output_semantic_name, + gs_output_semantic_index, + FALSE, + FALSE); stgp->num_inputs = gs_num_inputs; stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL ); |