X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_glsl_to_tgsi.cpp;h=7564119ac11a55c17e317bae254efc0966815253;hb=a2dc11a7818c04d8dc0324e8fcba98d60baea529;hp=06b4bb41a9b1075ba7767847d55d474b129f08d8;hpb=2c3f95d6aaab38cd66dd3dee1b089d5c91928eea;p=mesa.git diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 06b4bb41a9b..7564119ac11 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -52,6 +52,8 @@ #include "st_program.h" #include "st_mesa_to_tgsi.h" #include "st_format.h" +#include "st_glsl_types.h" +#include "st_nir.h" #define PROGRAM_ANY_CONST ((1 << PROGRAM_STATE_VAR) | \ @@ -89,7 +91,7 @@ public: this->is_double_vertex_input = false; } - st_src_reg(gl_register_file file, int index, int type) + st_src_reg(gl_register_file file, int index, enum glsl_base_type type) { this->type = type; this->file = file; @@ -105,7 +107,7 @@ public: this->is_double_vertex_input = false; } - st_src_reg(gl_register_file file, int index, int type, int index2D) + st_src_reg(gl_register_file file, int index, enum glsl_base_type type, int index2D) { this->type = type; this->file = file; @@ -144,7 +146,7 @@ public: int index2D; GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ int negate; /**< NEGATE_XYZW mask from mesa */ - int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ + enum glsl_base_type 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; @@ -160,7 +162,7 @@ public: class st_dst_reg { public: - st_dst_reg(gl_register_file file, int writemask, int type, int index) + st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index) { this->file = file; this->index = index; @@ -173,7 +175,7 @@ public: this->array_id = 0; } - st_dst_reg(gl_register_file file, int writemask, int type) + st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type) { this->file = file; this->index = 0; @@ -205,7 +207,7 @@ public: int index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */ int index2D; int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ - int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ + enum glsl_base_type 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; @@ -341,10 +343,10 @@ struct array_decl { unsigned mesa_index; unsigned array_id; unsigned array_size; - unsigned array_type; + enum glsl_base_type array_type; }; -static unsigned +static enum glsl_base_type find_array_type(struct array_decl *arrays, unsigned count, unsigned array_id) { unsigned i; @@ -374,7 +376,7 @@ public: struct gl_context *ctx; struct gl_program *prog; struct gl_shader_program *shader_program; - struct gl_shader *shader; + struct gl_linked_shader *shader; struct gl_shader_compiler_options *options; int next_temp; @@ -389,7 +391,7 @@ public: unsigned num_output_arrays; int num_address_regs; - int samplers_used; + uint32_t samplers_used; glsl_base_type sampler_types[PIPE_MAX_SAMPLERS]; int sampler_targets[PIPE_MAX_SAMPLERS]; /**< One of TGSI_TEXTURE_* */ int buffers_used; @@ -418,7 +420,7 @@ public: st_src_reg st_src_reg_for_double(double val); st_src_reg st_src_reg_for_float(float val); st_src_reg st_src_reg_for_int(int val); - st_src_reg st_src_reg_for_type(int type, int val); + st_src_reg st_src_reg_for_type(enum glsl_base_type type, int val); /** * \name Visit methods @@ -450,6 +452,8 @@ public: virtual void visit(ir_barrier *); /*@}*/ + void visit_expression(ir_expression *, st_src_reg *) ATTRIBUTE_NOINLINE; + void visit_atomic_counter_intrinsic(ir_call *); void visit_ssbo_intrinsic(ir_call *); void visit_membar_intrinsic(ir_call *); @@ -625,7 +629,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op, { glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction(); int num_reladdr = 0, i, j; - bool dst_is_double[2]; + bool dst_is_64bit[2]; op = get_opcode(ir, op, dst, src0, src1); @@ -728,18 +732,16 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op, * GLSL [0].w -> TGSI [1].zw */ for (j = 0; j < 2; j++) { - dst_is_double[j] = false; - if (inst->dst[j].type == GLSL_TYPE_DOUBLE) - dst_is_double[j] = true; - else if (inst->dst[j].file == PROGRAM_OUTPUT && inst->dst[j].type == GLSL_TYPE_ARRAY) { - unsigned type = find_array_type(this->output_arrays, this->num_output_arrays, inst->dst[j].array_id); - if (type == GLSL_TYPE_DOUBLE) - dst_is_double[j] = true; + dst_is_64bit[j] = glsl_base_type_is_64bit(inst->dst[j].type); + if (!dst_is_64bit[j] && inst->dst[j].file == PROGRAM_OUTPUT && inst->dst[j].type == GLSL_TYPE_ARRAY) { + enum glsl_base_type type = find_array_type(this->output_arrays, this->num_output_arrays, inst->dst[j].array_id); + if (glsl_base_type_is_64bit(type)) + dst_is_64bit[j] = true; } } - if (dst_is_double[0] || dst_is_double[1] || - inst->src[0].type == GLSL_TYPE_DOUBLE) { + if (dst_is_64bit[0] || dst_is_64bit[1] || + glsl_base_type_is_64bit(inst->src[0].type)) { glsl_to_tgsi_instruction *dinst = NULL; int initial_src_swz[4], initial_src_idx[4]; int initial_dst_idx[2], initial_dst_writemask[2]; @@ -791,7 +793,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op, /* modify the destination if we are splitting */ for (j = 0; j < 2; j++) { - if (dst_is_double[j]) { + if (dst_is_64bit[j]) { dinst->dst[j].writemask = (i & 1) ? WRITEMASK_ZW : WRITEMASK_XY; dinst->dst[j].index = initial_dst_idx[j]; if (i > 1) { @@ -812,7 +814,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op, for (j = 0; j < 4; j++) { int swz = GET_SWZ(initial_src_swz[j], i); - if (dinst->src[j].type == GLSL_TYPE_DOUBLE) { + if (glsl_base_type_is_64bit(dinst->src[j].type)) { dinst->src[j].index = initial_src_idx[j]; if (swz > 1) { dinst->src[j].double_reg2 = true; @@ -829,7 +831,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op, - F2D is a float src0, DLDEXP is integer src1 */ if (op == TGSI_OPCODE_F2D || op == TGSI_OPCODE_DLDEXP || - (op == TGSI_OPCODE_UCMP && dst_is_double[0])) { + (op == TGSI_OPCODE_UCMP && dst_is_64bit[0])) { dinst->src[j].swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz); } } @@ -862,7 +864,7 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, st_dst_reg dst, st_src_reg src0, st_src_reg src1) { - int type = GLSL_TYPE_FLOAT; + enum glsl_base_type type = GLSL_TYPE_FLOAT; if (op == TGSI_OPCODE_MOV) return op; @@ -1151,7 +1153,7 @@ glsl_to_tgsi_visitor::st_src_reg_for_int(int val) } st_src_reg -glsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) +glsl_to_tgsi_visitor::st_src_reg_for_type(enum glsl_base_type type, int val) { if (native_integers) return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : @@ -1163,72 +1165,13 @@ glsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) static int attrib_type_size(const struct glsl_type *type, bool is_vs_input) { - unsigned int i; - int size; - - switch (type->base_type) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: - case GLSL_TYPE_FLOAT: - case GLSL_TYPE_BOOL: - if (type->is_matrix()) { - return type->matrix_columns; - } else { - /* Regardless of size of vector, it gets a vec4. This is bad - * packing for things like floats, but otherwise arrays become a - * mess. Hopefully a later pass over the code can pack scalars - * down if appropriate. - */ - return 1; - } - break; - case GLSL_TYPE_DOUBLE: - if (type->is_matrix()) { - if (type->vector_elements <= 2 || is_vs_input) - return type->matrix_columns; - else - return type->matrix_columns * 2; - } else { - /* For doubles if we have a double or dvec2 they fit in one - * vec4, else they need 2 vec4s. - */ - if (type->vector_elements <= 2 || is_vs_input) - return 1; - else - return 2; - } - break; - case GLSL_TYPE_ARRAY: - assert(type->length > 0); - return attrib_type_size(type->fields.array, is_vs_input) * type->length; - case GLSL_TYPE_STRUCT: - size = 0; - for (i = 0; i < type->length; i++) { - size += attrib_type_size(type->fields.structure[i].type, is_vs_input); - } - return size; - case GLSL_TYPE_SAMPLER: - case GLSL_TYPE_IMAGE: - case GLSL_TYPE_SUBROUTINE: - /* Samplers take up one slot in UNIFORMS[], but they're baked in - * at link time. - */ - return 1; - case GLSL_TYPE_ATOMIC_UINT: - case GLSL_TYPE_INTERFACE: - case GLSL_TYPE_VOID: - case GLSL_TYPE_ERROR: - case GLSL_TYPE_FUNCTION: - assert(!"Invalid type in type_size"); - break; - } - return 0; + return st_glsl_attrib_type_size(type, is_vs_input); } static int type_size(const struct glsl_type *type) { - return attrib_type_size(type, false); + return st_glsl_type_size(type); } /** @@ -1535,10 +1478,7 @@ glsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir, void glsl_to_tgsi_visitor::visit(ir_expression *ir) { - unsigned int operand; st_src_reg op[ARRAY_SIZE(ir->operands)]; - st_src_reg result_src; - st_dst_reg result_dst; /* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c) */ @@ -1561,7 +1501,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) if (ir->operation == ir_quadop_vector) assert(!"ir_quadop_vector should have been lowered"); - for (operand = 0; operand < ir->get_num_operands(); operand++) { + for (unsigned int operand = 0; operand < ir->get_num_operands(); operand++) { this->result.file = PROGRAM_UNDEFINED; ir->operands[operand]->accept(this); if (this->result.file == PROGRAM_UNDEFINED) { @@ -1578,6 +1518,19 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) assert(!ir->operands[operand]->type->is_matrix()); } + visit_expression(ir, op); +} + +/* The non-recursive part of the expression visitor lives in a separate + * function and should be prevented from being inlined, to avoid a stack + * explosion when deeply nested expressions are visited. + */ +void +glsl_to_tgsi_visitor::visit_expression(ir_expression* ir, st_src_reg *op) +{ + st_src_reg result_src; + st_dst_reg result_dst; + int vector_elements = ir->operands[0]->type->vector_elements; if (ir->operands[1]) { vector_elements = MAX2(vector_elements, @@ -1946,13 +1899,15 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) if (have_sqrt) { emit_scalar(ir, TGSI_OPCODE_SQRT, result_dst, op[0]); } else { - /* sqrt(x) = x * rsq(x). */ - emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); - emit_asm(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]); - /* For incoming channels <= 0, set the result to 0. */ - op[0].negate = ~op[0].negate; - emit_asm(ir, TGSI_OPCODE_CMP, result_dst, - op[0], result_src, st_src_reg_for_float(0.0)); + /* This is the only instruction sequence that makes the game "Risen" + * render correctly. ABS is not required for the game, but since GLSL + * declares negative values as "undefined", allowing us to do whatever + * we want, I choose to use ABS to match DX9 and pre-GLSL RSQ + * behavior. + */ + emit_scalar(ir, TGSI_OPCODE_ABS, result_dst, op[0]); + emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, result_src); + emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, result_src); } break; case ir_unop_rsq: @@ -2003,12 +1958,14 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); break; case ir_unop_bitcast_f2i: - result_src = op[0]; - result_src.type = GLSL_TYPE_INT; - break; case ir_unop_bitcast_f2u: - result_src = op[0]; - result_src.type = GLSL_TYPE_UINT; + /* Make sure we don't propagate the negate modifier to integer opcodes. */ + if (op[0].negate) + emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]); + else + result_src = op[0]; + result_src.type = ir->operation == ir_unop_bitcast_f2i ? GLSL_TYPE_INT : + GLSL_TYPE_UINT; break; case ir_unop_bitcast_i2f: case ir_unop_bitcast_u2f: @@ -2136,7 +2093,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) } cbuf.swizzle = swizzle_for_size(ir->type->vector_elements); - if (cbuf.type == GLSL_TYPE_DOUBLE) + if (glsl_base_type_is_64bit(cbuf.type)) cbuf.swizzle += MAKE_SWIZZLE4(const_offset % 16 / 8, const_offset % 16 / 8, const_offset % 16 / 8, @@ -2197,9 +2154,29 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_unop_interpolate_at_centroid: emit_asm(ir, TGSI_OPCODE_INTERP_CENTROID, result_dst, op[0]); break; - case ir_binop_interpolate_at_offset: - emit_asm(ir, TGSI_OPCODE_INTERP_OFFSET, result_dst, op[0], op[1]); + case ir_binop_interpolate_at_offset: { + /* The y coordinate needs to be flipped for the default fb */ + static const gl_state_index transform_y_state[STATE_LENGTH] + = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM }; + + unsigned transform_y_index = + _mesa_add_state_reference(this->prog->Parameters, + transform_y_state); + + st_src_reg transform_y = st_src_reg(PROGRAM_STATE_VAR, + transform_y_index, + glsl_type::vec4_type); + transform_y.swizzle = SWIZZLE_XXXX; + + st_src_reg temp = get_temp(glsl_type::vec2_type); + st_dst_reg temp_dst = st_dst_reg(temp); + + emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[1]); + temp_dst.writemask = WRITEMASK_Y; + emit_asm(ir, TGSI_OPCODE_MUL, temp_dst, transform_y, op[1]); + emit_asm(ir, TGSI_OPCODE_INTERP_OFFSET, result_dst, op[0], temp); break; + } case ir_binop_interpolate_at_sample: emit_asm(ir, TGSI_OPCODE_INTERP_SAMPLE, result_dst, op[0], op[1]); break; @@ -2251,13 +2228,23 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) GLSL_TYPE_UINT); if (!const_offset) { buffer.reladdr = ralloc(mem_ctx, st_src_reg); - memcpy(buffer.reladdr, &sampler_reladdr, sizeof(sampler_reladdr)); + *buffer.reladdr = op[0]; emit_arl(ir, sampler_reladdr, op[0]); } emit_asm(ir, TGSI_OPCODE_RESQ, result_dst)->buffer = buffer; break; } + case ir_unop_vote_any: + emit_asm(ir, TGSI_OPCODE_VOTE_ANY, result_dst, op[0]); + break; + case ir_unop_vote_all: + emit_asm(ir, TGSI_OPCODE_VOTE_ALL, result_dst, op[0]); + break; + case ir_unop_vote_eq: + emit_asm(ir, TGSI_OPCODE_VOTE_EQ, result_dst, op[0]); + break; + case ir_unop_pack_snorm_2x16: case ir_unop_pack_unorm_2x16: case ir_unop_pack_snorm_4x8: @@ -2472,7 +2459,8 @@ shrink_array_declarations(struct array_decl *arrays, unsigned count, GLbitfield64 double_usage_mask, GLbitfield patch_usage_mask) { - unsigned i, j; + unsigned i; + int j; /* Fix array declarations by removing unused array elements at both ends * of the arrays. For example, mat4[3] where only mat[1] is used. @@ -2481,7 +2469,7 @@ shrink_array_declarations(struct array_decl *arrays, unsigned count, struct array_decl *decl = &arrays[i]; /* Shrink the beginning. */ - for (j = 0; j < decl->array_size; j++) { + for (j = 0; j < (int)decl->array_size; j++) { if (decl->mesa_index >= VARYING_SLOT_PATCH0) { if (patch_usage_mask & BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j)) @@ -2836,7 +2824,7 @@ glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type * } l->index++; r->index++; - if (type->is_dual_slot_double()) { + if (type->is_dual_slot()) { l->index++; if (r->is_double_vertex_input == false) r->index++; @@ -2862,7 +2850,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); if (ir->lhs->type->is_array() || ir->lhs->type->without_array()->is_matrix()) { - if (ir->lhs->type->without_array()->is_double()) { + if (ir->lhs->type->without_array()->is_64bit()) { switch (ir->lhs->type->without_array()->vector_elements) { case 1: l.writemask = WRITEMASK_X; @@ -2881,7 +2869,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) l.writemask = WRITEMASK_XYZW; } } else if (ir->lhs->type->is_scalar() && - !ir->lhs->type->is_double() && + !ir->lhs->type->is_64bit() && ir->lhs->variable_referenced()->data.mode == ir_var_shader_out) { /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the * FINISHME: W component of fragment shader output zero, work correctly. @@ -3261,9 +3249,9 @@ glsl_to_tgsi_visitor::visit_ssbo_intrinsic(ir_call *ir) if (!const_block) { block->accept(this); - emit_arl(ir, sampler_reladdr, this->result); buffer.reladdr = ralloc(mem_ctx, st_src_reg); - memcpy(buffer.reladdr, &sampler_reladdr, sizeof(sampler_reladdr)); + *buffer.reladdr = this->result; + emit_arl(ir, sampler_reladdr, this->result); } /* Calculate the surface offset */ @@ -3348,7 +3336,7 @@ glsl_to_tgsi_visitor::visit_ssbo_intrinsic(ir_call *ir) inst = (glsl_to_tgsi_instruction *)inst->get_prev(); if (inst->op == TGSI_OPCODE_UADD) inst = (glsl_to_tgsi_instruction *)inst->get_prev(); - } while (inst && inst->buffer.file == PROGRAM_UNDEFINED && inst->op == op); + } while (inst && inst->op == op && inst->buffer.file == PROGRAM_UNDEFINED); } void @@ -3478,9 +3466,9 @@ glsl_to_tgsi_visitor::visit_image_intrinsic(ir_call *ir) get_deref_offsets(img, &sampler_array_size, &sampler_base, (unsigned int *)&image.index, &reladdr); if (reladdr.file != PROGRAM_UNDEFINED) { - emit_arl(ir, sampler_reladdr, reladdr); image.reladdr = ralloc(mem_ctx, st_src_reg); - memcpy(image.reladdr, &sampler_reladdr, sizeof(reladdr)); + *image.reladdr = reladdr; + emit_arl(ir, sampler_reladdr, reladdr); } st_dst_reg dst = undef_dst; @@ -3499,9 +3487,9 @@ glsl_to_tgsi_visitor::visit_image_intrinsic(ir_call *ir) st_src_reg res = get_temp(glsl_type::ivec4_type); st_dst_reg dstres = st_dst_reg(res); dstres.writemask = WRITEMASK_W; - emit_asm(ir, TGSI_OPCODE_RESQ, dstres); + inst = emit_asm(ir, TGSI_OPCODE_RESQ, dstres); res.swizzle = SWIZZLE_WWWW; - inst = emit_asm(ir, TGSI_OPCODE_MOV, dst, res); + emit_asm(ir, TGSI_OPCODE_MOV, dst, res); } else { st_src_reg arg1 = undef_src, arg2 = undef_src; st_src_reg coord; @@ -3891,7 +3879,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) ir->coordinate->accept(this); /* Put our coords in a temp. We'll need to modify them for shadow, - * projection, or LOD, so the only case we'd use it as is is if + * projection, or LOD, so the only case we'd use it as-is is if * we're doing plain old texturing. The optimization passes on * glsl_to_tgsi_visitor should handle cleaning up our mess in that case. */ @@ -4290,6 +4278,8 @@ glsl_to_tgsi_visitor::visit(ir_barrier *ir) glsl_to_tgsi_visitor::glsl_to_tgsi_visitor() { + STATIC_ASSERT(sizeof(samplers_used) * 8 >= PIPE_MAX_SAMPLERS); + result.file = PROGRAM_UNDEFINED; next_temp = 1; array_sizes = NULL; @@ -4346,7 +4336,7 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog) if (inst->info->is_tex) { for (int i = 0; i < inst->sampler_array_size; i++) { unsigned idx = inst->sampler_base + i; - v->samplers_used |= 1 << idx; + v->samplers_used |= 1u << idx; debug_assert(idx < (int)ARRAY_SIZE(v->sampler_types)); v->sampler_types[idx] = inst->tex_type; @@ -4482,6 +4472,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void) && inst->dst[0].writemask == get_src_arg_mask(inst->dst[0], inst->src[2])) { inst->op = TGSI_OPCODE_MOV; + inst->info = tgsi_get_opcode_info(inst->op); inst->src[0] = inst->src[1]; } } @@ -4982,7 +4973,7 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) delete inst; removed++; } else { - if (inst->dst[0].type == GLSL_TYPE_DOUBLE) { + if (glsl_base_type_is_64bit(inst->dst[0].type)) { if (inst->dead_mask == WRITEMASK_XY || inst->dead_mask == WRITEMASK_ZW) inst->dst[0].writemask &= ~(inst->dead_mask); @@ -5184,49 +5175,78 @@ struct st_translate { unsigned insn_size; unsigned insn_count; - unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */ + unsigned procType; /**< PIPE_SHADER_VERTEX/FRAGMENT */ boolean error; }; /** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */ -const unsigned _mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { - /* Vertex shader - */ - TGSI_SEMANTIC_VERTEXID, - TGSI_SEMANTIC_INSTANCEID, - TGSI_SEMANTIC_VERTEXID_NOBASE, - TGSI_SEMANTIC_BASEVERTEX, - TGSI_SEMANTIC_BASEINSTANCE, - TGSI_SEMANTIC_DRAWID, - - /* Geometry shader - */ - TGSI_SEMANTIC_INVOCATIONID, - - /* Fragment shader - */ - TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_FACE, - TGSI_SEMANTIC_SAMPLEID, - TGSI_SEMANTIC_SAMPLEPOS, - TGSI_SEMANTIC_SAMPLEMASK, - TGSI_SEMANTIC_HELPER_INVOCATION, - - /* Tessellation shaders - */ - TGSI_SEMANTIC_TESSCOORD, - TGSI_SEMANTIC_VERTICESIN, - TGSI_SEMANTIC_PRIMID, - TGSI_SEMANTIC_TESSOUTER, - TGSI_SEMANTIC_TESSINNER, +unsigned +_mesa_sysval_to_semantic(unsigned sysval) +{ + switch (sysval) { + /* Vertex shader */ + case SYSTEM_VALUE_VERTEX_ID: + return TGSI_SEMANTIC_VERTEXID; + case SYSTEM_VALUE_INSTANCE_ID: + return TGSI_SEMANTIC_INSTANCEID; + case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: + return TGSI_SEMANTIC_VERTEXID_NOBASE; + case SYSTEM_VALUE_BASE_VERTEX: + return TGSI_SEMANTIC_BASEVERTEX; + case SYSTEM_VALUE_BASE_INSTANCE: + return TGSI_SEMANTIC_BASEINSTANCE; + case SYSTEM_VALUE_DRAW_ID: + return TGSI_SEMANTIC_DRAWID; + + /* Geometry shader */ + case SYSTEM_VALUE_INVOCATION_ID: + return TGSI_SEMANTIC_INVOCATIONID; + + /* Fragment shader */ + case SYSTEM_VALUE_FRAG_COORD: + return TGSI_SEMANTIC_POSITION; + case SYSTEM_VALUE_FRONT_FACE: + return TGSI_SEMANTIC_FACE; + case SYSTEM_VALUE_SAMPLE_ID: + return TGSI_SEMANTIC_SAMPLEID; + case SYSTEM_VALUE_SAMPLE_POS: + return TGSI_SEMANTIC_SAMPLEPOS; + case SYSTEM_VALUE_SAMPLE_MASK_IN: + return TGSI_SEMANTIC_SAMPLEMASK; + case SYSTEM_VALUE_HELPER_INVOCATION: + return TGSI_SEMANTIC_HELPER_INVOCATION; + + /* Tessellation shader */ + case SYSTEM_VALUE_TESS_COORD: + return TGSI_SEMANTIC_TESSCOORD; + case SYSTEM_VALUE_VERTICES_IN: + return TGSI_SEMANTIC_VERTICESIN; + case SYSTEM_VALUE_PRIMITIVE_ID: + return TGSI_SEMANTIC_PRIMID; + case SYSTEM_VALUE_TESS_LEVEL_OUTER: + return TGSI_SEMANTIC_TESSOUTER; + case SYSTEM_VALUE_TESS_LEVEL_INNER: + return TGSI_SEMANTIC_TESSINNER; + + /* Compute shader */ + case SYSTEM_VALUE_LOCAL_INVOCATION_ID: + return TGSI_SEMANTIC_THREAD_ID; + case SYSTEM_VALUE_WORK_GROUP_ID: + return TGSI_SEMANTIC_BLOCK_ID; + case SYSTEM_VALUE_NUM_WORK_GROUPS: + return TGSI_SEMANTIC_GRID_SIZE; + + /* Unhandled */ + case SYSTEM_VALUE_LOCAL_INVOCATION_INDEX: + case SYSTEM_VALUE_GLOBAL_INVOCATION_ID: + case SYSTEM_VALUE_VERTEX_CNT: + default: + assert(!"Unexpected SYSTEM_VALUE_ enum"); + return TGSI_SEMANTIC_COUNT; + } +} - /* Compute shaders - */ - TGSI_SEMANTIC_THREAD_ID, - TGSI_SEMANTIC_BLOCK_ID, - TGSI_SEMANTIC_GRID_SIZE, -}; /** * Make note of a branch to a label in the TGSI code. @@ -5317,7 +5337,7 @@ dst_register(struct st_translate *t, gl_register_file file, unsigned index, case PROGRAM_TEMPORARY: /* Allocate space for temporaries on demand. */ if (index >= t->temps_size) { - const int inc = 4096; + const int inc = align(index - t->temps_size + 1, 4096); t->temps = (struct ureg_dst*) realloc(t->temps, @@ -5348,10 +5368,10 @@ dst_register(struct st_translate *t, gl_register_file file, unsigned index, case PROGRAM_OUTPUT: if (!array_id) { - if (t->procType == TGSI_PROCESSOR_FRAGMENT) + if (t->procType == PIPE_SHADER_FRAGMENT) assert(index < FRAG_RESULT_MAX); - else if (t->procType == TGSI_PROCESSOR_TESS_CTRL || - t->procType == TGSI_PROCESSOR_TESS_EVAL) + else if (t->procType == PIPE_SHADER_TESS_CTRL || + t->procType == PIPE_SHADER_TESS_EVAL) assert(index < VARYING_SLOT_TESS_MAX); else assert(index < VARYING_SLOT_MAX); @@ -5538,6 +5558,15 @@ translate_tex_offset(struct st_translate *t, offset.SwizzleZ = imm_src.SwizzleZ; offset.Padding = 0; break; + case PROGRAM_INPUT: + imm_src = t->inputs[t->inputMapping[in_offset->index]]; + offset.File = imm_src.File; + offset.Index = imm_src.Index; + offset.SwizzleX = GET_SWZ(in_offset->swizzle, 0); + offset.SwizzleY = GET_SWZ(in_offset->swizzle, 1); + offset.SwizzleZ = GET_SWZ(in_offset->swizzle, 2); + offset.Padding = 0; + break; case PROGRAM_TEMPORARY: imm_src = ureg_src(t->temps[in_offset->index]); offset.File = imm_src.File; @@ -5805,7 +5834,7 @@ emit_wpos(struct st_context *st, * * The bias of the y-coordinate depends on whether y-inversion takes place * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are - * drawing to an FBO (causes additional inversion), and whether the the pipe + * drawing to an FBO (causes additional inversion), and whether the pipe * driver origin and the requested origin differ (the latter condition is * stored in the 'invert' variable). * @@ -5935,6 +5964,20 @@ find_array(unsigned attr, struct array_decl *arrays, unsigned count, return false; } +static void +emit_compute_block_size(const struct gl_program *program, + struct ureg_program *ureg) { + const struct gl_compute_program *cp = + (const struct gl_compute_program *)program; + + ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH, + cp->LocalSize[0]); + ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT, + cp->LocalSize[1]); + ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH, + cp->LocalSize[2]); +} + /** * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format. * \param program the program to translate @@ -5984,35 +6027,6 @@ st_translate_program( assert(numInputs <= ARRAY_SIZE(t->inputs)); assert(numOutputs <= ARRAY_SIZE(t->outputs)); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_FRONT_FACE] == - TGSI_SEMANTIC_FACE); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_VERTEX_ID] == - TGSI_SEMANTIC_VERTEXID); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_INSTANCE_ID] == - TGSI_SEMANTIC_INSTANCEID); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_SAMPLE_ID] == - TGSI_SEMANTIC_SAMPLEID); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_SAMPLE_POS] == - TGSI_SEMANTIC_SAMPLEPOS); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_SAMPLE_MASK_IN] == - TGSI_SEMANTIC_SAMPLEMASK); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_INVOCATION_ID] == - TGSI_SEMANTIC_INVOCATIONID); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE] == - TGSI_SEMANTIC_VERTEXID_NOBASE); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_BASE_VERTEX] == - TGSI_SEMANTIC_BASEVERTEX); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_TESS_COORD] == - TGSI_SEMANTIC_TESSCOORD); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_HELPER_INVOCATION] == - TGSI_SEMANTIC_HELPER_INVOCATION); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_LOCAL_INVOCATION_ID] == - TGSI_SEMANTIC_THREAD_ID); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_WORK_GROUP_ID] == - TGSI_SEMANTIC_BLOCK_ID); - assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_NUM_WORK_GROUPS] == - TGSI_SEMANTIC_GRID_SIZE); - t = CALLOC_STRUCT(st_translate); if (!t) { ret = PIPE_ERROR_OUT_OF_MEMORY; @@ -6032,7 +6046,7 @@ st_translate_program( * Declare input attributes. */ switch (procType) { - case TGSI_PROCESSOR_FRAGMENT: + case PIPE_SHADER_FRAGMENT: for (i = 0; i < numInputs; i++) { unsigned array_id = 0; unsigned array_size; @@ -6053,9 +6067,9 @@ st_translate_program( } } break; - case TGSI_PROCESSOR_GEOMETRY: - case TGSI_PROCESSOR_TESS_EVAL: - case TGSI_PROCESSOR_TESS_CTRL: + case PIPE_SHADER_GEOMETRY: + case PIPE_SHADER_TESS_EVAL: + case PIPE_SHADER_TESS_CTRL: for (i = 0; i < numInputs; i++) { unsigned array_id = 0; unsigned array_size; @@ -6074,12 +6088,12 @@ st_translate_program( } } break; - case TGSI_PROCESSOR_VERTEX: + case PIPE_SHADER_VERTEX: for (i = 0; i < numInputs; i++) { t->inputs[i] = ureg_DECL_vs_input(ureg, i); } break; - case TGSI_PROCESSOR_COMPUTE: + case PIPE_SHADER_COMPUTE: break; default: assert(0); @@ -6089,13 +6103,13 @@ st_translate_program( * Declare output attributes. */ switch (procType) { - case TGSI_PROCESSOR_FRAGMENT: - case TGSI_PROCESSOR_COMPUTE: + case PIPE_SHADER_FRAGMENT: + case PIPE_SHADER_COMPUTE: break; - case TGSI_PROCESSOR_GEOMETRY: - case TGSI_PROCESSOR_TESS_EVAL: - case TGSI_PROCESSOR_TESS_CTRL: - case TGSI_PROCESSOR_VERTEX: + case PIPE_SHADER_GEOMETRY: + case PIPE_SHADER_TESS_EVAL: + case PIPE_SHADER_TESS_CTRL: + case PIPE_SHADER_VERTEX: for (i = 0; i < numOutputs; i++) { unsigned array_id = 0; unsigned array_size; @@ -6120,8 +6134,8 @@ st_translate_program( assert(0); } - if (procType == TGSI_PROCESSOR_FRAGMENT) { - if (program->shader->EarlyFragmentTests) + if (procType == PIPE_SHADER_FRAGMENT) { + if (program->shader->info.EarlyFragmentTests) ureg_property(ureg, TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL, 1); if (proginfo->InputsRead & VARYING_BIT_POS) { @@ -6168,7 +6182,7 @@ st_translate_program( } } } - else if (procType == TGSI_PROCESSOR_VERTEX) { + else if (procType == PIPE_SHADER_VERTEX) { for (i = 0; i < numOutputs; i++) { if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) { /* force register to contain a fog coordinate in the form (F, 0, 0, 1). */ @@ -6180,6 +6194,10 @@ st_translate_program( } } + if (procType == PIPE_SHADER_COMPUTE) { + emit_compute_block_size(proginfo, ureg); + } + /* Declare address register. */ if (program->num_address_regs > 0) { @@ -6195,7 +6213,7 @@ st_translate_program( for (i = 0; sysInputs; i++) { if (sysInputs & (1 << i)) { - unsigned semName = _mesa_sysval_to_semantic[i]; + unsigned semName = _mesa_sysval_to_semantic(i); t->systemValues[i] = ureg_DECL_system_value(ureg, semName, 0); @@ -6210,7 +6228,7 @@ st_translate_program( */ struct st_context *st = st_context(ctx); struct pipe_screen *pscreen = st->pipe->screen; - assert(procType == TGSI_PROCESSOR_VERTEX); + assert(procType == PIPE_SHADER_VERTEX); assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS)); (void) pscreen; if (!ctx->Const.NativeIntegers) { @@ -6220,7 +6238,7 @@ st_translate_program( } } - if (procType == TGSI_PROCESSOR_FRAGMENT && + if (procType == PIPE_SHADER_FRAGMENT && semName == TGSI_SEMANTIC_POSITION) emit_wpos(st_context(ctx), t, proginfo, ureg, program->wpos_transform_const); @@ -6307,7 +6325,7 @@ st_translate_program( /* texture samplers */ for (i = 0; i < frag_const->MaxTextureImageUnits; i++) { - if (program->samplers_used & (1 << i)) { + if (program->samplers_used & (1u << i)) { unsigned type; t->samplers[i] = ureg_DECL_sampler(ureg, i); @@ -6372,8 +6390,8 @@ st_translate_program( /* Set the next shader stage hint for VS and TES. */ switch (procType) { - case TGSI_PROCESSOR_VERTEX: - case TGSI_PROCESSOR_TESS_EVAL: + case PIPE_SHADER_VERTEX: + case PIPE_SHADER_TESS_EVAL: if (program->shader_program->SeparateShader) break; @@ -6383,16 +6401,16 @@ st_translate_program( switch (i) { case MESA_SHADER_TESS_CTRL: - next = TGSI_PROCESSOR_TESS_CTRL; + next = PIPE_SHADER_TESS_CTRL; break; case MESA_SHADER_TESS_EVAL: - next = TGSI_PROCESSOR_TESS_EVAL; + next = PIPE_SHADER_TESS_EVAL; break; case MESA_SHADER_GEOMETRY: - next = TGSI_PROCESSOR_GEOMETRY; + next = PIPE_SHADER_GEOMETRY; break; case MESA_SHADER_FRAGMENT: - next = TGSI_PROCESSOR_FRAGMENT; + next = PIPE_SHADER_FRAGMENT; break; default: assert(0); @@ -6434,16 +6452,16 @@ out: * generating Mesa IR. */ static struct gl_program * -get_mesa_program(struct gl_context *ctx, - struct gl_shader_program *shader_program, - struct gl_shader *shader) +get_mesa_program_tgsi(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_linked_shader *shader) { glsl_to_tgsi_visitor* v; struct gl_program *prog; GLenum target = _mesa_shader_stage_to_program(shader->Stage); bool progress; struct gl_shader_compiler_options *options = - &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader->Type)]; + &ctx->Const.ShaderCompilerOptions[shader->Stage]; struct pipe_screen *pscreen = ctx->st->pipe->screen; unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage); @@ -6538,8 +6556,8 @@ get_mesa_program(struct gl_context *ctx, /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */ v->simplify_cmp(); - if (shader->Type != GL_TESS_CONTROL_SHADER && - shader->Type != GL_TESS_EVALUATION_SHADER) + if (shader->Stage != MESA_SHADER_TESS_CTRL && + shader->Stage != MESA_SHADER_TESS_EVAL) v->copy_propagate(); while (v->eliminate_dead_code()); @@ -6575,7 +6593,7 @@ get_mesa_program(struct gl_context *ctx, shader->ir = NULL; /* This must be done before the uniform storage is associated. */ - if (shader->Type == GL_FRAGMENT_SHADER && + if (shader->Stage == MESA_SHADER_FRAGMENT && (prog->InputsRead & VARYING_BIT_POS || prog->SystemValuesRead & (1 << SYSTEM_VALUE_FRAG_COORD))) { static const gl_state_index wposTransformState[STATE_LENGTH] = { @@ -6611,28 +6629,28 @@ get_mesa_program(struct gl_context *ctx, struct st_tesseval_program *sttep; struct st_compute_program *stcp; - switch (shader->Type) { - case GL_VERTEX_SHADER: + switch (shader->Stage) { + case MESA_SHADER_VERTEX: stvp = (struct st_vertex_program *)prog; stvp->glsl_to_tgsi = v; break; - case GL_FRAGMENT_SHADER: + case MESA_SHADER_FRAGMENT: stfp = (struct st_fragment_program *)prog; stfp->glsl_to_tgsi = v; break; - case GL_GEOMETRY_SHADER: + case MESA_SHADER_GEOMETRY: stgp = (struct st_geometry_program *)prog; stgp->glsl_to_tgsi = v; break; - case GL_TESS_CONTROL_SHADER: + case MESA_SHADER_TESS_CTRL: sttcp = (struct st_tessctrl_program *)prog; sttcp->glsl_to_tgsi = v; break; - case GL_TESS_EVALUATION_SHADER: + case MESA_SHADER_TESS_EVAL: sttep = (struct st_tesseval_program *)prog; sttep->glsl_to_tgsi = v; break; - case GL_COMPUTE_SHADER: + case MESA_SHADER_COMPUTE: stcp = (struct st_compute_program *)prog; stcp->glsl_to_tgsi = v; break; @@ -6644,73 +6662,31 @@ get_mesa_program(struct gl_context *ctx, return prog; } -extern "C" { - -static void -st_dump_program_for_shader_db(struct gl_context *ctx, - struct gl_shader_program *prog) +static struct gl_program * +get_mesa_program(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_linked_shader *shader) { - /* Dump only successfully compiled and linked shaders to the specified - * file. This is for shader-db. - * - * These options allow some pre-processing of shaders while dumping, - * because some apps have ill-formed shaders. - */ - const char *dump_filename = os_get_option("ST_DUMP_SHADERS"); - const char *insert_directives = os_get_option("ST_DUMP_INSERT"); - - if (dump_filename && prog->Name != 0) { - FILE *f = fopen(dump_filename, "a"); - - if (f) { - for (unsigned i = 0; i < prog->NumShaders; i++) { - const struct gl_shader *sh = prog->Shaders[i]; - const char *source; - bool skip_version = false; - - if (!sh) - continue; - - source = sh->Source; - - /* This string mustn't be changed. shader-db uses it to find - * where the shader begins. - */ - fprintf(f, "GLSL %s shader %d source for linked program %d:\n", - _mesa_shader_stage_to_string(sh->Stage), - i, prog->Name); - - /* Dump the forced version if set. */ - if (ctx->Const.ForceGLSLVersion) { - fprintf(f, "#version %i\n", ctx->Const.ForceGLSLVersion); - skip_version = true; - } - - /* Insert directives (optional). */ - if (insert_directives) { - if (!ctx->Const.ForceGLSLVersion && prog->Version) - fprintf(f, "#version %i\n", prog->Version); - fprintf(f, "%s\n", insert_directives); - skip_version = true; - } - - if (skip_version && strncmp(source, "#version ", 9) == 0) { - const char *next_line = strstr(source, "\n"); - - if (next_line) - source = next_line + 1; - else - continue; - } - - fprintf(f, "%s", source); - fprintf(f, "\n"); - } - fclose(f); + struct pipe_screen *pscreen = ctx->st->pipe->screen; + unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage); + enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir) + pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_PREFERRED_IR); + if (preferred_ir == PIPE_SHADER_IR_NIR) { + /* TODO only for GLSL VS/FS for now: */ + switch (shader->Stage) { + case MESA_SHADER_VERTEX: + case MESA_SHADER_FRAGMENT: + return st_nir_get_mesa_program(ctx, shader_program, shader); + default: + break; } } + return get_mesa_program_tgsi(ctx, shader_program, shader); } + +extern "C" { + /** * Link a shader. * Called via ctx->Driver.LinkShader() @@ -6729,7 +6705,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; - gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(prog->_LinkedShaders[i]->Type); + gl_shader_stage stage = prog->_LinkedShaders[i]->Stage; const struct gl_shader_compiler_options *options = &ctx->Const.ShaderCompilerOptions[stage]; unsigned ptarget = st_shader_stage_to_ptarget(stage); @@ -6785,7 +6761,21 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) (have_dround ? 0 : DOPS_TO_DFRAC) | (options->EmitNoPow ? POW_TO_EXP2 : 0) | (!ctx->Const.NativeIntegers ? INT_DIV_TO_MUL_RCP : 0) | - (options->EmitNoSat ? SAT_TO_CLAMP : 0)); + (options->EmitNoSat ? SAT_TO_CLAMP : 0) | + /* Assume that if ARB_gpu_shader5 is not supported + * then all of the extended integer functions need + * lowering. It may be necessary to add some caps + * for individual instructions. + */ + (!ctx->Extensions.ARB_gpu_shader5 + ? BIT_COUNT_TO_MATH | + EXTRACT_TO_SHIFTS | + INSERT_TO_SHIFTS | + REVERSE_TO_SHIFTS | + FIND_LSB_TO_FLOAT_CAST | + FIND_MSB_TO_FLOAT_CAST | + IMUL_HIGH_TO_MUL + : 0)); do_vec_index_to_cond_assign(ir); lower_vector_insert(ir, true); @@ -6811,7 +6801,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) validate_ir_tree(ir); } - build_program_resource_list(prog); + build_program_resource_list(ctx, prog); for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_program *linked_prog; @@ -6837,7 +6827,6 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) _mesa_reference_program(ctx, &linked_prog, NULL); } - st_dump_program_for_shader_db(ctx, prog); return GL_TRUE; } @@ -6846,9 +6835,17 @@ st_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi, const GLuint outputMapping[], struct pipe_stream_output_info *so) { - unsigned i; struct gl_transform_feedback_info *info = &glsl_to_tgsi->shader_program->LinkedTransformFeedback; + st_translate_stream_output_info2(info, outputMapping, so); +} + +void +st_translate_stream_output_info2(struct gl_transform_feedback_info *info, + const GLuint outputMapping[], + struct pipe_stream_output_info *so) +{ + unsigned i; for (i = 0; i < info->NumOutputs; i++) { so->output[i].register_index = @@ -6861,7 +6858,7 @@ st_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi, } for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { - so->stride[i] = info->BufferStride[i]; + so->stride[i] = info->Buffers[i].Stride; } so->num_outputs = info->NumOutputs; }