/** * 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))); }
/** * Emit a PS input (or VS depth/fog output) register declaration. * For example, if usage = SVGA3D_DECLUSAGE_TEXCOORD, reg.num = 1, and * index = 3, we'll emit "dcl_texcoord3 v1". */ static boolean emit_decl(struct svga_shader_emitter *emit, SVGA3dShaderDestToken reg, unsigned usage, unsigned index) { SVGA3DOpDclArgs dcl; SVGA3dShaderInstToken opcode; /* check values against bitfield sizes */ assert(index < 16); assert(usage <= SVGA3D_DECLUSAGE_MAX); opcode = inst_token( SVGA3DOP_DCL ); dcl.values[0] = 0; dcl.values[1] = 0; dcl.dst = reg; 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))); }
static boolean vs20_input( struct svga_shader_emitter *emit, struct tgsi_declaration_semantic semantic, unsigned idx ) { SVGA3DOpDclArgs dcl; SVGA3dShaderInstToken opcode; 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); /* Mesa doesn't provide use with VS input semantics (they're * actually pretty meaningless), so we just generate some plausible * ones here. This has to match what we declare in the vdecl code * in svga_pipe_vertex.c. */ if (idx == 0) { dcl.usage = SVGA3D_DECLUSAGE_POSITION; dcl.index = 0; } else { dcl.usage = SVGA3D_DECLUSAGE_TEXCOORD; dcl.index = idx - 1; } dcl.values[0] |= 1<<31; return (emit_instruction(emit, opcode) && svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); }
static boolean ps20_input( struct svga_shader_emitter *emit, struct tgsi_declaration_semantic semantic, unsigned idx ) { struct src_register reg; SVGA3DOpDclArgs dcl; SVGA3dShaderInstToken opcode; opcode = inst_token( SVGA3DOP_DCL ); dcl.values[0] = 0; dcl.values[1] = 0; switch (semantic.SemanticName) { case TGSI_SEMANTIC_POSITION: /* Special case: */ reg = src_register( SVGA3DREG_MISCTYPE, SVGA3DMISCREG_POSITION ); break; case TGSI_SEMANTIC_COLOR: reg = src_register( SVGA3DREG_INPUT, semantic.SemanticIndex ); break; case TGSI_SEMANTIC_FOG: assert(semantic.SemanticIndex == 0); reg = src_register( SVGA3DREG_TEXTURE, 0 ); break; case TGSI_SEMANTIC_GENERIC: reg = src_register( SVGA3DREG_TEXTURE, semantic.SemanticIndex + 1 ); break; default: assert(0); return TRUE; } emit->input_map[idx] = reg; dcl.dst = dst( reg ); dcl.usage = 0; dcl.index = 0; dcl.values[0] |= 1<<31; return (emit_instruction(emit, opcode) && svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); }
static boolean ps20_sampler( struct svga_shader_emitter *emit, struct tgsi_declaration_semantic semantic, unsigned idx ) { SVGA3DOpDclArgs dcl; SVGA3dShaderInstToken opcode; opcode = inst_token( SVGA3DOP_DCL ); dcl.values[0] = 0; dcl.values[1] = 0; dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx ); dcl.type = svga_tgsi_sampler_type( emit, idx ); 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; }
/** * Declare a VS output. * VS3.0 outputs have proper declarations and semantic info for * matching against PS inputs. */ static boolean vs30_output(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 (!translate_vs_ps_semantic( emit, semantic, &usage, &index )) return FALSE; if (emit->vs30_output_count >= SVGA3D_OUTPUTREG_MAX) return FALSE; dcl.dst = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ ); dcl.usage = usage; dcl.index = index; dcl.values[0] |= 1<<31; if (semantic.Name == TGSI_SEMANTIC_POSITION) { assert(idx == 0); emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, emit->nr_hw_temp++ ); emit->temp_pos = emit->output_map[idx]; emit->true_pos = dcl.dst; /* Grab an extra output for the depth output */ if (!vs30_output_emit_depth_fog( emit, &emit->depth_pos )) return FALSE; } else if (semantic.Name == TGSI_SEMANTIC_PSIZE) { emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, emit->nr_hw_temp++ ); emit->temp_psiz = emit->output_map[idx]; /* This has the effect of not declaring psiz (below) and not * emitting the final MOV to true_psiz in the postamble. */ if (!emit->key.vs.allow_psiz) return TRUE; emit->true_psiz = dcl.dst; } else if (semantic.Name == TGSI_SEMANTIC_FOG) { /* * Fog is shared with depth. * So we need to decrement out_count since emit_depth_fog will increment it. */ emit->vs30_output_count--; if (!vs30_output_emit_depth_fog( emit, &emit->output_map[idx] )) return FALSE; return TRUE; } else { emit->output_map[idx] = dcl.dst; } return (emit_instruction(emit, opcode) && svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); }