/** * Declare a VS input register. * We still make up the input semantics the same as in 2.0 */ static boolean vs30_input(struct svga_shader_emitter *emit, struct tgsi_declaration_semantic semantic, unsigned idx) { SVGA3DOpDclArgs dcl; SVGA3dShaderInstToken opcode; unsigned usage, index; opcode = inst_token( SVGA3DOP_DCL ); dcl.values[0] = 0; dcl.values[1] = 0; emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx ); dcl.dst = dst_register( SVGA3DREG_INPUT, idx ); assert(dcl.dst.reserved0); svga_generate_vdecl_semantics( idx, &usage, &index ); dcl.usage = usage; dcl.index = index; dcl.values[0] |= 1<<31; return (emit_instruction(emit, opcode) && svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); }
/** * Declare a VS input register. * We still make up the input semantics the same as in 2.0 */ static boolean vs30_input(struct svga_shader_emitter *emit, struct tgsi_declaration_semantic semantic, unsigned idx) { SVGA3DOpDclArgs dcl; SVGA3dShaderInstToken opcode; unsigned usage, index; opcode = inst_token( SVGA3DOP_DCL ); dcl.values[0] = 0; dcl.values[1] = 0; if (emit->key.vkey.zero_stride_vertex_elements & (1 << idx)) { unsigned i; unsigned offset = 0; unsigned start_idx = emit->info.file_max[TGSI_FILE_CONSTANT] + 1; /* adjust for prescale constants */ start_idx += emit->key.vkey.need_prescale ? 2 : 0; /* compute the offset from the start of zero stride constants */ for (i = 0; i < PIPE_MAX_ATTRIBS && i < idx; ++i) { if (emit->key.vkey.zero_stride_vertex_elements & (1<<i)) ++offset; } emit->input_map[idx] = src_register( SVGA3DREG_CONST, start_idx + offset ); } else { emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx ); dcl.dst = dst_register( SVGA3DREG_INPUT, idx ); assert(dcl.dst.reserved0); svga_generate_vdecl_semantics( idx, &usage, &index ); dcl.usage = usage; dcl.index = index; dcl.values[0] |= 1<<31; return (emit_instruction(emit, opcode) && svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); } return TRUE; }
static int emit_hw_vs_vdecl( struct svga_context *svga, unsigned dirty ) { const struct pipe_vertex_element *ve = svga->curr.ve; SVGA3dVertexDecl decl; unsigned i; assert(svga->curr.num_vertex_elements >= svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]); svga_hwtnl_reset_vdecl( svga->hwtnl, svga->curr.num_vertex_elements ); for (i = 0; i < svga->curr.num_vertex_elements; i++) { const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; unsigned usage, index; svga_generate_vdecl_semantics( i, &usage, &index ); /* SVGA_NEW_VELEMENT */ decl.identity.type = svga->state.sw.ve_format[i]; decl.identity.method = SVGA3D_DECLMETHOD_DEFAULT; decl.identity.usage = usage; decl.identity.usageIndex = index; decl.array.stride = vb->stride; decl.array.offset = (vb->buffer_offset + ve[i].src_offset); svga_hwtnl_vdecl( svga->hwtnl, i, &decl, vb->buffer ); } return 0; }
static enum pipe_error emit_hw_vs_vdecl(struct svga_context *svga, unsigned dirty) { const struct pipe_vertex_element *ve = svga->curr.velems->velem; SVGA3dVertexDecl decls[SVGA3D_INPUTREG_MAX]; unsigned buffer_indexes[SVGA3D_INPUTREG_MAX]; unsigned i; unsigned neg_bias = 0; assert(svga->curr.velems->count >= svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]); /** * We can't set the VDECL offset to something negative, so we * must calculate a common negative additional index bias, and modify * the VDECL offsets accordingly so they *all* end up positive. * * Note that the exact value of the negative index bias is not that * important, since we compensate for it when we calculate the vertex * buffer offset below. The important thing is that all vertex buffer * offsets remain positive. * * Note that we use a negative bias variable in order to make the * rounding maths more easy to follow, and to avoid int / unsigned * confusion. */ for (i = 0; i < svga->curr.velems->count; i++) { const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; struct svga_buffer *buffer; unsigned int offset = vb->buffer_offset + ve[i].src_offset; unsigned tmp_neg_bias = 0; if (!vb->buffer) continue; buffer = svga_buffer(vb->buffer); if (buffer->uploaded.start > offset) { tmp_neg_bias = buffer->uploaded.start - offset; if (vb->stride) tmp_neg_bias = (tmp_neg_bias + vb->stride - 1) / vb->stride; neg_bias = MAX2(neg_bias, tmp_neg_bias); } } for (i = 0; i < svga->curr.velems->count; i++) { const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; unsigned usage, index; struct svga_buffer *buffer; if (!vb->buffer) continue; buffer = svga_buffer(vb->buffer); svga_generate_vdecl_semantics( i, &usage, &index ); /* SVGA_NEW_VELEMENT */ decls[i].identity.type = svga->curr.velems->decl_type[i]; decls[i].identity.method = SVGA3D_DECLMETHOD_DEFAULT; decls[i].identity.usage = usage; decls[i].identity.usageIndex = index; decls[i].array.stride = vb->stride; /* Compensate for partially uploaded vbo, and * for the negative index bias. */ decls[i].array.offset = (vb->buffer_offset + ve[i].src_offset + neg_bias * vb->stride - buffer->uploaded.start); assert(decls[i].array.offset >= 0); buffer_indexes[i] = ve[i].vertex_buffer_index; assert(!buffer->uploaded.buffer); } svga_hwtnl_vertex_decls(svga->hwtnl, svga->curr.velems->count, decls, buffer_indexes, svga->curr.velems->id); svga_hwtnl_vertex_buffers(svga->hwtnl, svga->curr.num_vertex_buffers, svga->curr.vb); svga_hwtnl_set_index_bias( svga->hwtnl, -(int) neg_bias ); return PIPE_OK; }