Commits

Anonymous committed fa93f06

added comment for GLSL OCL builtin-header files to README, fixed handling of kernel var enums, fixed struct opaque handling in preparator

Comments (0)

Files changed (6)

                   AST - Extractor for LLVM
                           (axtor)
 --------------------------------------------------------------
-date    : 05.03.12
+date    : 17.09.12
 author  : Simon Moll
 licence : GPL (read file "LICENSE")
 
 as well.
 
 ##### Build Prerequisites #####
-LLVM 3.1 (last tested revision 152026)
+LLVM 3.1 (release)
 
 
 ##### Build Instructions #####
 	both the extractor and oclang. 
 	(read tools/axtorOCLDriver/README for details).
 	
+tools/axtorIntrinsicHeaders
+
+	Installs headers for using OCL/GLSL builtin functions with C++/C through Clang. After installations,
+	these headers can be found in the llvm/include directory "axtor_glsl/GLSL_Intrinsics.h"
+	"axtor_ocl/OpenCL_Intrinsics.h", respectively.
 	
 	
 ##### References #####

lib/axtor/backend/generic/GenericCSerializer.cpp

 				TypeSet undeclaredTypes;
 
 				for (StructTypeVector::iterator itType = types.begin(); itType != types.end(); ++itType) {
+					if ((*itType)->getStructNumElements() > 0) //opqaue types don't need to be declared
 					undeclaredTypes.insert(*itType);
 				}
 
 					const std::string name = modInfo.getTypeName(*itType);
 
 					if (
+							(type->getStructNumElements() == 0) || // don't declare opaque types
 							undeclaredTypes.find(type) == undeclaredTypes.end() || //already declared
 							containsType(type, undeclaredTypes))
 					{

lib/axtor/pass/Preparator.cpp

 				itStruct != structTypes.end();
 				++itStruct, ++idx)
 		{
-			std::string genericName = "StructType" + str<uint>(idx);
-			if (modInfo.setTypeName(*itStruct, genericName)) {
-				Log::warn("Type name " + genericName + " already in use!");
+			llvm::StructType * structType = (*itStruct);
+
+			// only remove the class. / struct. prefix from opaque types, if existent
+			if (structType->getStructNumElements() == 0) {
+				std::string opaqueName = structType->getStructName();
+				if (opaqueName.substr(0, 6) == "class.") {
+					structType->setName(opaqueName.substr(6, std::string::npos));
+				} else if (opaqueName.substr(0, 7) == "struct.") {
+					structType->setName(opaqueName.substr(7, std::string::npos));
+				}
+
+			// give all other structures a generic name
+			} else {
+				std::string genericName = "StructType" + str<uint>(idx);
+				if (modInfo.setTypeName(*itStruct, genericName)) {
+					Log::warn("Type name " + genericName + " already in use!");
+				}
 			}
 		}
 	}

lib/axtor_ocl/OCLEnum.cpp

  */
 
 #include <axtor_ocl/OCLEnum.h>
-
+#include <axtor_ocl/OCLEnumValues.h>
 #include <axtor/util/llvmConstant.h>
 
+#define SAMPLER_CASE(STR,NAME)  case NAME:STR=#NAME; break;
+
 bool axtor::evaluateEnum_MemFence(llvm::Value * val, std::string & result)
 {
 	uint64_t enumIndex;
 
 	switch(enumIndex)
 	{
-	case 0: result = "CLK_LOCAL_MEM_FENCE"; break;
-	case 1: result = "CLK_GLOBAL_MEM_FENCE"; break;
+		SAMPLER_CASE(result, CLK_LOCAL_MEM_FENCE)
+		SAMPLER_CASE(result, CLK_GLOBAL_MEM_FENCE)
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+
+bool axtor::evaluateEnum_Sampler(size_t cfg, std::string & result)
+{
+		std::string normStr;
+	switch (cfg & 1)
+	{
+		SAMPLER_CASE(normStr, CLK_NORMALIZED_COORDS_FALSE)
+		SAMPLER_CASE(normStr, CLK_NORMALIZED_COORDS_TRUE)
+	}
+
+	std::string addStr;
+	switch ((cfg >> 2) & 3)
+	{
+		SAMPLER_CASE(addStr, CLK_ADDRESS_NONE)
+		SAMPLER_CASE(addStr, CLK_ADDRESS_REPEAT)
+		SAMPLER_CASE(addStr, CLK_ADDRESS_CLAMP_TO_EDGE)
+		SAMPLER_CASE(addStr, CLK_ADDRESS_CLAMP32)
 	default:
 		return false;
 	}
 
+	std::string filterStr;
+	switch ((cfg >> 3) & 1)
+	{
+		SAMPLER_CASE(filterStr, CLK_FILTER_NEAREST)
+		SAMPLER_CASE(filterStr, CLK_FILTER_LINEAR)
+	default:
+			return false;
+	}
+
+	result = normStr + " | " + addStr + " | " + filterStr;
+
 	return true;
 }
+
+#undef SAMPLER_CASE
+

lib/axtor_ocl/OCLWriter.cpp

 			std::string result = calleeName + "(" + enumStr + ")";
 			return result;
 
+		} else if (callee->getName() == FAKE_GLOBAL_SAMPLER_NAME) {
+			std::string calleeName = callee->getName();
+
+			llvm::Value * arg = call->getArgOperand(0);
+			size_t cfg;
+
+			if (! evaluateInt(arg, cfg)) {
+				Log::fail(call, "expected enum value");
+			}
+			std::string samplerName = "samplerGlobal" + hexstr(cfg);
+
+			return samplerName;
 
 		} else { //regular intrinsic
 		#ifdef DEBUG
    putLineBreak();
 }
 
+
+void OCLWriter::emitGlobalSamplers()
+{
+	llvm::Module * mod = modInfo.getModule();
+	llvm::Function * fakeSampler = mod->getFunction(FAKE_GLOBAL_SAMPLER_NAME);
+
+	IntSet requiredSamplers;
+
+	if (!fakeSampler)
+		return;
+
+	// collect all required sampler values
+	for (llvm::Value::use_iterator itUse = fakeSampler->use_begin(); itUse != fakeSampler->use_end(); ++itUse)
+	{
+		llvm::Value * user = *itUse;
+		assert( llvm::isa<llvm::CallInst>(user) && "can only call this function");
+		llvm::CallInst * call = llvm::cast<llvm::CallInst>(user);
+		llvm::Value * enumVal = call->getArgOperand(0);
+
+		size_t cfg;
+		if (! evaluateInt(enumVal, cfg))
+			Log::fail(user, "Could not infer enum value");
+
+		requiredSamplers.insert((int) cfg);
+	}
+
+	// emit sampler declarations
+	for (IntSet::const_iterator itCfg = requiredSamplers.begin(); itCfg != requiredSamplers.end(); ++itCfg) {
+		int cfg = *itCfg;
+		std::string cfgStr;
+		if (evaluateEnum_Sampler(cfg, cfgStr)) {
+			std::string samplerStr = "const sampler_t samplerGlobal" + hexstr(cfg) + " = " + cfgStr + ";";
+			putLine(samplerStr);
+		} else {
+			Log::warn("can not decode sampler values. Will not create sampler constant.");
+		}
+	}
+
+}
+
+
 /*
 * dumps a generic vertex shader and all type&argument defs for the frag shader
 */
 
 		putLine( "" );
 
+		//## create constants for requested sampler types
+		emitGlobalSamplers();
+
+		putLine( "" );
+
 		//## spill function declarations
 		for (llvm::Module::iterator func = mod->begin(); func != mod->end(); ++func)
 		{

tools/axtorIntrinsicHeaders/include/Compute_Api.h

 	return r;
 }
 
+inline int2 i2_ctor_ii(int x, int y)
+{
+	int2 r;
+	r.x = x;
+	r.y = y;
+	return r;
+}
+
 inline int4 i4_ctor_iiii(int x, int y, int z, int w)
 {
 	int4 r;
 
 extern "C"
 {
-
+	// generic types
 	#include <axtor_ocl/OCL_Intrinsics.def>
+
+	//FIXME sampler hack
+	sampler_t NOPTR* fake_global_sampler(int config);
 }
 
 #include "UndefIntrinsicMakros.h"