static void llvm_load_input( struct radeon_llvm_context * ctx, unsigned input_index, const struct tgsi_full_declaration *decl) { const struct r600_shader_io * input = &ctx->r600_inputs[input_index]; unsigned chan; int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR); LLVMValueRef v; boolean require_interp_intrinsic = ctx->chip_class >= EVERGREEN && ctx->type == TGSI_PROCESSOR_FRAGMENT; if (require_interp_intrinsic && input->spi_sid) { v = llvm_load_input_vector(ctx, input->lds_pos, input->ij_index, (input->interpolate > 0)); } else v = LLVMGetParam(ctx->main_fn, input->gpr); if (two_side) { struct r600_shader_io * back_input = &ctx->r600_inputs[input->back_color_input]; LLVMValueRef v2; LLVMValueRef face = LLVMGetParam(ctx->main_fn, ctx->face_gpr); face = LLVMBuildExtractElement(ctx->gallivm.builder, face, lp_build_const_int32(&(ctx->gallivm), 0), ""); if (require_interp_intrinsic && back_input->spi_sid) v2 = llvm_load_input_vector(ctx, back_input->lds_pos, back_input->ij_index, (back_input->interpolate > 0)); else v2 = LLVMGetParam(ctx->main_fn, back_input->gpr); v = llvm_face_select_helper(ctx, face, v, v2); } for (chan = 0; chan < 4; chan++) { unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan); ctx->inputs[soa_index] = LLVMBuildExtractElement(ctx->gallivm.builder, v, lp_build_const_int32(&(ctx->gallivm), chan), ""); if (input->name == TGSI_SEMANTIC_POSITION && ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == 3) { /* RCP for fragcoord.w */ ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder, lp_build_const_float(&(ctx->gallivm), 1.0f), ctx->inputs[soa_index], ""); } } }
static void llvm_load_input( struct radeon_llvm_context * ctx, unsigned input_index, const struct tgsi_full_declaration *decl) { unsigned chan; const char *intrinsics = "llvm.R600.load.input"; unsigned offset = 4 * ctx->reserved_reg_count; if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->chip_class >= EVERGREEN) { switch (decl->Interp.Interpolate) { case TGSI_INTERPOLATE_COLOR: case TGSI_INTERPOLATE_PERSPECTIVE: offset = 0; intrinsics = "llvm.R600.load.input.perspective"; break; case TGSI_INTERPOLATE_LINEAR: offset = 0; intrinsics = "llvm.R600.load.input.linear"; break; case TGSI_INTERPOLATE_CONSTANT: offset = 0; intrinsics = "llvm.R600.load.input.constant"; break; default: assert(0 && "Unknow Interpolate mode"); } } for (chan = 0; chan < 4; chan++) { unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan); switch (decl->Semantic.Name) { case TGSI_SEMANTIC_FACE: ctx->inputs[soa_index] = llvm_load_input_helper(ctx, "llvm.R600.load.input", 4 * ctx->face_input); break; case TGSI_SEMANTIC_POSITION: if (ctx->type != TGSI_PROCESSOR_FRAGMENT || chan != 3) { ctx->inputs[soa_index] = llvm_load_input_helper(ctx, "llvm.R600.load.input", soa_index + (ctx->reserved_reg_count * 4)); } else { LLVMValueRef w_coord = llvm_load_input_helper(ctx, "llvm.R600.load.input", soa_index + (ctx->reserved_reg_count * 4)); ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder, lp_build_const_float(&(ctx->gallivm), 1.0f), w_coord, ""); } break; case TGSI_SEMANTIC_COLOR: if (ctx->two_side) { unsigned front_location, back_location; unsigned back_reg = ctx->r600_inputs[input_index] .potential_back_facing_reg; if (ctx->chip_class >= EVERGREEN) { front_location = 4 * ctx->r600_inputs[input_index].lds_pos + chan; back_location = 4 * ctx->r600_inputs[back_reg].lds_pos + chan; } else { front_location = soa_index + 4 * ctx->reserved_reg_count; back_location = radeon_llvm_reg_index_soa( ctx->r600_inputs[back_reg].gpr, chan); } ctx->inputs[soa_index] = llvm_face_select_helper(ctx, intrinsics, 4 * ctx->face_input, front_location, back_location); break; } default: { unsigned location; if (ctx->chip_class >= EVERGREEN) { location = 4 * ctx->r600_inputs[input_index].lds_pos + chan; } else { location = soa_index + 4 * ctx->reserved_reg_count; } /* The * 4 is assuming that we are in soa mode. */ ctx->inputs[soa_index] = llvm_load_input_helper(ctx, intrinsics, location); break; } } } }