diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom.c | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_constbuf.c | 17 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.c | 6 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 101 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_program.c | 128 |
6 files changed, 206 insertions, 48 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_atom.c b/mesalib/src/mesa/state_tracker/st_atom.c index 1abaf8f3e..682073ed6 100644 --- a/mesalib/src/mesa/state_tracker/st_atom.c +++ b/mesalib/src/mesa/state_tracker/st_atom.c @@ -66,6 +66,7 @@ static const struct st_tracked_state *atoms[] = &st_update_fs_constants, &st_bind_vs_ubos, &st_bind_fs_ubos, + &st_bind_gs_ubos, &st_update_pixel_transfer, /* this must be done after the vertex program update */ diff --git a/mesalib/src/mesa/state_tracker/st_atom.h b/mesalib/src/mesa/state_tracker/st_atom.h index 101a3a6bd..ef24face9 100644 --- a/mesalib/src/mesa/state_tracker/st_atom.h +++ b/mesalib/src/mesa/state_tracker/st_atom.h @@ -69,6 +69,7 @@ extern const struct st_tracked_state st_update_gs_constants; extern const struct st_tracked_state st_update_vs_constants; extern const struct st_tracked_state st_bind_fs_ubos; extern const struct st_tracked_state st_bind_vs_ubos; +extern const struct st_tracked_state st_bind_gs_ubos; extern const struct st_tracked_state st_update_pixel_transfer; diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c index 723ab561c..f3c457625 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c +++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c @@ -254,4 +254,21 @@ const struct st_tracked_state st_bind_fs_ubos = { bind_fs_ubos }; +static void bind_gs_ubos(struct st_context *st) +{ + struct gl_shader_program *prog = st->ctx->Shader.CurrentGeometryProgram; + + if (!prog) + return; + + st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY], PIPE_SHADER_GEOMETRY); +} +const struct st_tracked_state st_bind_gs_ubos = { + "st_bind_gs_ubos", + { + 0, + ST_NEW_GEOMETRY_PROGRAM | ST_NEW_UNIFORM_BUFFER, + }, + bind_gs_ubos +}; diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index 80393cff7..4e0d98cc3 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -125,6 +125,9 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, st->dirty.mesa = ~0; st->dirty.st = ~0; + /* Create upload manager for vertex data for glBitmap, glDrawPixels, + * glClear, etc. + */ st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) { @@ -148,7 +151,8 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, st_init_draw( st ); st_init_generate_mipmap(st); - if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) + /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */ + if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) st->internal_target = PIPE_TEXTURE_2D; else st->internal_target = PIPE_TEXTURE_RECT; diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 8d06ac6f7..3e11cce24 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/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/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index 60cc37cf8..f010e1889 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/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,15 +911,42 @@ 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_PSIZ: + stgp->input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; + stgp->input_semantic_index[slot] = 0; + break; case VARYING_SLOT_TEX0: + case VARYING_SLOT_TEX1: + case VARYING_SLOT_TEX2: + case VARYING_SLOT_TEX3: + case VARYING_SLOT_TEX4: + case VARYING_SLOT_TEX5: + 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; } } } @@ -929,7 +957,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. @@ -972,6 +999,26 @@ 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_LAYER: + gs_output_semantic_name[slot] = TGSI_SEMANTIC_LAYER; + gs_output_semantic_index[slot] = 0; + break; + case VARYING_SLOT_PRIMITIVE_ID: + gs_output_semantic_name[slot] = TGSI_SEMANTIC_PRIMID; + gs_output_semantic_index[slot] = 0; + break; case VARYING_SLOT_TEX0: case VARYING_SLOT_TEX1: case VARYING_SLOT_TEX2: @@ -980,20 +1027,22 @@ 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); } } } - assert(gs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - /* find max output slot referenced to compute gs_num_outputs */ for (attr = 0; attr < VARYING_SLOT_MAX; attr++) { if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot) @@ -1031,23 +1080,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 ); |