}
-/**
- * -----------------------------------------------------------------------------
- * Deference IO intrinsic down to a single slot
- * Borrorwed & modified from LunarGlass GLSL Bottom translator DereferenceName
- * -----------------------------------------------------------------------------
- */
-ir_rvalue*
-MesaGlassTranslator::dereferenceIO(ir_rvalue* aggregate,
- const llvm::Type* type,
- const llvm::MDNode* mdAggregate,
- int slotOffset,
- EMdTypeLayout& mdTypeLayout,
- int irMode)
-{
- if (type->getTypeID() == llvm::Type::PointerTyID) {
- type = type->getContainedType(0);
-
- aggregate = dereferenceIO(aggregate, type, mdAggregate, slotOffset, mdTypeLayout, irMode);
- } else if (type->getTypeID() == llvm::Type::StructTyID) {
- int field = 0;
- int operand;
- const llvm::StructType* structType = llvm::dyn_cast<const llvm::StructType>(type);
- const llvm::Type* fieldType;
- do {
- operand = GetAggregateMdSubAggregateOp(field);
- if (operand >= int(mdAggregate->getNumOperands())) {
- assert(operand < int(mdAggregate->getNumOperands()));
- return aggregate;
- }
- fieldType = structType->getContainedType(field);
- const int fieldSize = CountSlots(fieldType);
- if (fieldSize > slotOffset)
- break;
- slotOffset -= fieldSize;
- ++field;
- } while (true);
-
- const char *field_name = ralloc_strdup(shader,
- mdAggregate->getOperand(GetAggregateMdNameOp(field))->getName().str().c_str());
-
- const llvm::MDNode* subMdAggregate = llvm::dyn_cast<const llvm::MDNode>(mdAggregate->getOperand(operand));
-
- // interface block members are hoisted to global scope in HIR
- if (anonBlocks.find(aggregate->type->name) != anonBlocks.end()) {
- aggregate = newIRVariableDeref(llvmTypeToHirType(fieldType), field_name, irMode);
- } else {
- aggregate = new(shader) ir_dereference_record(aggregate, field_name);
- }
-
- aggregate = dereferenceIO(aggregate, fieldType, subMdAggregate, slotOffset, mdTypeLayout, irMode);
-
- } else if (type->getTypeID() == llvm::Type::ArrayTyID) {
- const llvm::ArrayType* arrayType = llvm::dyn_cast<const llvm::ArrayType>(type);
- const int elementSize = CountSlots(arrayType->getContainedType(0));
- const int element = slotOffset / elementSize;
- slotOffset = slotOffset % elementSize;
-
- ir_rvalue* indexVal = new(shader) ir_constant(element);
-
- aggregate = new(shader) ir_dereference_array(aggregate, indexVal);
- aggregate = dereferenceIO(aggregate, arrayType->getContainedType(0), mdAggregate, slotOffset,
- mdTypeLayout, irMode);
-
- trackMaxArrayElement(aggregate, element);
- } else if (mdAggregate)
- mdTypeLayout = GetMdTypeLayout(mdAggregate);
-
- return aggregate;
-}
-
-
-/**
- * -----------------------------------------------------------------------------
- * Translate read & write data intrinsics
- * -----------------------------------------------------------------------------
- */
-inline void
-MesaGlassTranslator::emitIRIOIntrinsic(const llvm::IntrinsicInst* llvmInst, bool input)
-{
- std::string name;
- llvm::Type* mdType;
- EMdInputOutput mdQual;
- EMdPrecision mdPrecision;
- EMdTypeLayout mdLayout;
- int layoutLocation;
- const llvm::MDNode* mdAggregate;
- const llvm::MDNode* dummySampler;
- int interpMode;
-
- const llvm::MDNode* mdNode = llvmInst->getMetadata(input ? gla::InputMdName : gla::OutputMdName);
- assert(mdNode);
-
- // Glean information from metadata for intrinsic
- gla::CrackIOMd(mdNode, name, mdQual, mdType, mdLayout, mdPrecision, layoutLocation, dummySampler, mdAggregate, interpMode);
-
- // Create the name for anonymous block members
- if (name.empty()) {
- name = mdNode->getOperand(2)->getName();
- StripSuffix(name, "_typeProxy");
- StripSuffix(name, "_shadow");
- }
-
- const glsl_type* irType = llvmTypeToHirType(mdType->getContainedType(0), mdNode, llvmInst);
-
- const int slotOffset = GetConstantInt(llvmInst->getOperand(0)) - layoutLocation;
- const ir_variable_mode irMode = input ? ir_var_shader_in : ir_var_shader_out;
-
- ir_rvalue* ioVarDeref = newIRVariableDeref(irType, name, irMode);
-
- ir_variable* ioVar = ioVarDeref->as_dereference_variable()->variable_referenced();
-
- // ioVar->data.how_declared = ...
- ioVar->data.used = true;
-
- if (layoutLocation >= 0 && layoutLocation < gla::MaxUserLayoutLocation) {
- ioVar->data.explicit_location = true;
- ioVar->data.location = layoutLocation;
- }
-
- ioVar->data.index = slotOffset;
- // ioVar->data.explicit_index = ???
- // ioVar->data.explicit_binding
- // ioVar->data.has_initializer
- // ioVar->data.binding
- // ioVar->data.invariant
-
- // ioVar->data.interpolation = InterpolationQualifierToIR(gla::EInterpolationMethod(interpMode));
- ioVar->data.origin_upper_left = state->fs_origin_upper_left;
- ioVar->data.pixel_center_integer = state->fs_pixel_center_integer;
-
- ioVarDeref = dereferenceIO(ioVarDeref, mdType, mdAggregate, slotOffset, mdLayout, irMode);
-
- // TODO: handle write mask, add to ir_variable's mask
- if (input) {
- addIRInstruction(llvmInst, ioVarDeref);
- } else {
- ir_assignment* assign = new(shader) ir_assignment(ioVarDeref, getIRValue(llvmInst->getOperand(2)));
- addIRInstruction(llvmInst, assign);
- }
-}
-
-
/**
* -----------------------------------------------------------------------------
* Translate swizzle intrinsics