Commits

Anonymous committed eca81cf

Test codegeneration now has execute function, with parameters.
codegen also has a parameter map/array.

  • Participants
  • Parent commits 38affaf

Comments (0)

Files changed (5)

tests/codegen.lua

 	test.includes = {}
 	test.variables = {}
 	test.initialize = {}
+	test.execinit = {}
+	test.exec = {}
+	test.execfinal = {}
 	return test
 end
 
 
 codegen.vars = codegen.variables
 
+local function AddCodeStmts(dst, cmds, cmd_name)
+	if(type(cmds) == "string") then
+		dst[#dst + 1] = cmds
+	elseif(type(cmds) == "function") then
+		dst[#dst + 1] = cmds
+	elseif(type(input) == "table") then
+		for _,v in ipairs(input) do
+			AddCodeStmts(dst, v, cmd_name)
+		end
+	else
+		assert(nil, cmd_name .. " takes a string, function, or a table of such values.");
+	end
+end
+
 function codegen.initialize(init_cmds)
 	assert(codegen._curr, "Attempt to set initialization data for a suite/test that doesn't exist.")
 	
-	if(type(init_cmds) == "string") then
-		table.insert(codegen._curr.initialize, init_cmds)
-	elseif(type(init_cmds) == "function") then
-		table.insert(codegen._curr.initialize, init_cmds)
-	elseif(type(input) == "table") then
-		for _,v in ipairs(input) do
-			codegen.initialize(v)
-		end
-	else
-		assert(nil, "initialize takes a string, function, or a table of strings.");
-	end
+	AddCodeStmts(codegen._curr.initialize, init_cmds, "initialize")
 end
 
 codegen.init = codegen.initialize
 	set_flags(codegen._curr.render_flags, legalRenderFlags, render_flags, "render_flags")
 end
 
+function codegen.execinit(cmds)
+	assert_test("set initial execution code")
+	AddCodeStmts(codegen._curr.execinit, cmds, "execinit")
+end
+
+function codegen.exec(cmds)
+	assert_test("set execution code")
+	AddCodeStmts(codegen._curr.exec, cmds, "exec")
+end
+
+function codegen.execfinal(cmds)
+	assert_test("set execution finalization code")
+	AddCodeStmts(codegen._curr.execfinal, cmds, "execfinal")
+end
+
 --Build the environment that the codegen-loaded scripts execute within.
 local copyFromGlobal =
 {
 -------------------------------------------------------
 -- Code generation functions
 
+---------------------------
 --Preprocessing steps
 local function minmax(tbl)
 	local min, max
 end
 
 local function MakeParamIface(suite)
-	local paramIface = {}
-	suite._paramIface = paramIface
+	local param_iface = {}
+	suite._param_iface = param_iface
 	
 	for name, range in pairs(suite.params) do
 		if(range._rng == "range") then
 			local iface = {}
-			paramIface[name] = iface;
+			param_iface[name] = iface;
 			
 			local endval = range.first + range.count - 1
 			iface.min = range.first
 			end
 		else
 			local iface = {}
-			paramIface[name] = iface;
+			param_iface[name] = iface;
 
 			local min, max = minmax(range)
 			iface.min = min
 			end
 		end
 	end
-
 end
 
+local function MakeParamIndexMap(suite)
+	local param_map = {}
+	local param_array = {}
+
+	suite._param_map = param_map
+	suite._param_array = param_array
+
+	local currIx = 0
+	for name, range in pairs(suite.params) do
+		suite._param_map[name] = currIx
+		param_array[#param_array+1] = name
+		currIx = currIx + 1
+	end
+end
+
+local function PreprocessSuite(suite)
+	MakeParamIface(suite)
+	MakeParamIndexMap(suite)
+end
+
+---------------------------------------
 --Headers and includes.
 local function WriteInclude(hFile, hdrsWritten, include)
 	if(type(include) == "table") then
 	end
 end
 
--- Parameters.
+-------------------------------------
+-- Parameter definitions.
 local function WriteParamStructs(hFile, suite)
-	hFile:write([[
-struct ParamDefinition
-{
-	int min;
-	int max;
-	int count;
-	int *values;
-	
-	boost::iterator_range<const int *> range() const {return boost::iterator_range<const int *>(values, values + count);}
-};]])
+	hFile:write(gen.GetParamDefStructDefinition())
 	hFile:write("\n\n");
 	
-	for name, iface in pairs(suite._paramIface) do
+	for name, iface in pairs(suite._param_iface) do
 		hFile:write("const int ", gen.GetParamArrayVarname(name), "[] = {")
 		local temp = {}
 		for _, val in iface:iter() do
 	end
 end
 
+--------------------------------------
+-- Statements
 local function GetStmtString(suite, stmt)
 	if(type(stmt) == "string") then return stmt end
 	if(type(stmt) == "function") then
-		return stmt(suite._paramIface)
+		return stmt(suite._param_iface)
 	end
 
 	--TODO: Stmt can be a file. Load it.
 		currStmt = currStmt:gsub("%$" .. name, gen.GetParamDefVarname(name))
 	end
 	
-	hFile:write("\t\t", currStmt:gsub("%\n", "\n\t\t"), "\n\n")
+	hFile:write("\t\t", currStmt:gsub("%\n", "\n\t\t"), "\n")
+end
+
+-- Execution statements
+local function WriteAndFormatExecStmts(hFile, suite, stmt)
+	local currStmt = GetStmtString(suite, stmt)
+	
+	for name, range in pairs(suite.params) do
+		currStmt = currStmt:gsub("%$" .. name,
+			gen.GetParamValueVarname(suite._param_map[name]))
+	end
+	
+	hFile:write("\t\t", currStmt:gsub("%\n", "\n\t\t"), "\n")
+end
+
+local function WriteAndFormatExecStmtsList(hFile, suite, stmtList)
+	for _, stmt in ipairs(stmtList) do
+		WriteAndFormatExecStmts(hFile, suite, stmt)
+	end
 end
 
 -- Suite and test classes.
 		{type = "std::vector<GLuint>", destroy = "util::DestroyPrograms(%s);"},
 }
 
-local function WriteSuiteClass(hFile, suite)
-	hFile:write("struct ", gen.GetSuiteClassname(suite.name), "\n{\n")
-	
-	--Write variables first.
-	for varname, vartype in pairs(suite.variables) do
+local function WriteVariableList(hFile, class)
+	local bFound = false
+	for varname, vartype in pairs(class.variables) do
 		hFile:write("\t")
 		if(specialVarTypes[vartype]) then
 			hFile:write(specialVarTypes[vartype].type)
 		end
 		
 		hFile:write(" ", varname, ";\n")
+		bFound = true
 	end
-	hFile:write("\n")
+	
+	hFile:write(iif(bFound, "\n", ""))
+end
+
+local function WriteSuiteClass(hFile, suite)
+	hFile:write("struct ", gen.GetSuiteClassname(suite.name), "\n{\n")
+	
+	WriteVariableList(hFile, suite)
 	
 	--Write the constructor.
 	hFile:write("\t", gen.GetSuiteClassname(suite.name), "()\n\t{\n")
 	hFile:write("};\n");
 end
 
+local function WriteTestClass(hFile, test)
+	hFile:write("struct ", gen.GetTestClassname(test.name), "\n{\n")
+	
+	--Write variables first.
+	WriteVariableList(hFile, test)
+	
+	--Write the constructor.
+	hFile:write("\t", gen.GetTestClassname(test.name), "(", gen.GetSuiteFuncParam(test._suite), ")\n\t{\n")
+	for _, stmt in ipairs(test.initialize) do
+		WriteAndFormatInitStmts(hFile, test._suite, stmt)
+	end
+	hFile:write("\t}\n\n")
+	
+	--Write the destructor.
+	hFile:write("\t~", gen.GetTestClassname(test.name), "()\n\t{\n")
+	for varname, vartype in pairs(test.variables) do
+		if(specialVarTypes[vartype]) then
+			hFile:write("\t\t")
+			hFile:write(string.format(specialVarTypes[vartype].destroy, varname))
+			hFile:write("\n")
+		end
+	end
+	hFile:write("\t}\n\n")
+	
+	--Write execution function.
+	hFile:write("\tvoid ", gen.GetExecuteFuncName(), "(")
+	hFile:write("util::TestDatum &datum")
+	hFile:write(", ", gen.GetSuiteFuncParam(test._suite))
+	hFile:write(", ", gen.GetParamArgDef())
+	hFile:write(")\n\t{\n")
+	
+	--User initialization first.
+	WriteAndFormatExecStmtsList(hFile, test._suite, test.execinit)
+	
+	--TODO: Insert timing init code here.
+	
+	WriteAndFormatExecStmtsList(hFile, test._suite, test.exec)
+	
+	--TODO: Insert timing storage and finalization code here.
+	
+	WriteAndFormatExecStmtsList(hFile, test._suite, test.execfinal)
+	
+	hFile:write("\t}\n")
+
+	hFile:write("};\n");
+end
+
 function codegen.gencode()
 	for name, suite in pairs(codegen._suites) do
-		--Preprocessing of suite data.
-		MakeParamIface(suite)
+		PreprocessSuite(suite)
 	
 		local mainFilename = suite._base_dir .. "/" .. gen.GetMainFilename(name)
 
 		hFile:write("\n\n")
 		
 		WriteParamStructs(hFile, suite)
+		hFile:write(gen.GetParamValueStructDefinition(), "\n\n")
 		
 		WriteSuiteClass(hFile, suite)
 		hFile:write("\n\n")
 		
+		for testname, test in pairs(suite._tests) do	
+			WriteTestClass(hFile, test)
+		end
+		
 		
 		hFile:close()
-
-		--[[
-		print("Suite:", gen.GetMainFilename(name), suite._base_dir)
-		for testname, test in pairs(suite._tests) do
-			print("\tTest name:", testname)
-		end
-		]]
 	end
 end
 
+
+------------------------------------------
+-- Premake4 project/solution generation
+
+function codegen.genproj()
+	local cwd = os.getcwd()
+	for name, suite in pairs(codegen._suites) do
+		os.chdir(suite._base_dir)
+
+		project(name)
+			kind "ConsoleApp"
+			language "c++"
+			
+			files {"../util/*.h", "../util/*.cpp"}
+			files {"*_codegen.cpp"}
+--			files {"manual/*.h", "manual/*.cpp"}
+
+			includedirs "../../boost_1_51_0"
+				
+			--Must be after including framwork... because GCC is stupid.
+			UseLibs("glload", "glutil", "glm", "freeglut")
+			
+			configuration "Debug"
+				defines {"DEBUG", "_DEBUG"}
+				flags "Symbols"
+				targetname("manualD")
+
+			configuration "Release"
+				defines {"RELEASE", "NDEBUG"};
+				flags {"OptimizeSpeed", "NoFramePointer", "ExtraWarnings", "NoEditAndContinue"};
+				targetname("manual")
+
+			configuration {"windows"}
+				links {"glu32", "opengl32", "gdi32", "winmm", "user32"}
+
+			configuration "linux"
+				links {"GL", "GLU"}
+	end
+	os.chdir(cwd)
+end
+
 return codegen

tests/generate.lua

 	return "g_" .. paramName .. "_def"
 end
 
+function gen.GetParamArgVarname()
+	return "parameters"
+end
+
+function gen.GetParamArgDef()
+	return "const ParamValue *" .. gen.GetParamArgVarname()
+end
+
+function gen.GetParamValueVarname(paramIndex)
+	return string.format("%s[%i]", gen.GetParamArgVarname(), paramIndex)
+end
+
 function gen.WritePreamble(hFile, suite_name)
 	hFile:write([=[
 	/* Here's some preamble text. */
 	}
 end
 
+function gen.GetExecuteFuncName()
+	return "Execute"
+end
+
+function gen.GetSuiteFuncParam(suite)
+	return "const " .. gen.GetSuiteClassname(suite.name) .. " &suite"
+end
+
+function gen.GetParamDefStructDefinition()
+	return[[
+struct ParamDefinition
+{
+	int min;
+	int max;
+	int count;
+	const int *values;
+	
+	boost::iterator_range<const int *> range() const {return boost::iterator_range<const int *>(values, values + count);}
+};]]
+end
+
+function gen.GetParamValueStructDefinition()
+	return[[
+struct ParamValue
+{
+	int min;
+	int max;
+	int count;
+	const int *values;
+	int index;
+	int value;
+	
+	boost::iterator_range<const int *> range() const {return boost::iterator_range<const int *>(values, values + count);}
+	
+	ParamValue(const ParamDefinition &def, int index)
+		: min(def.min)
+		, max(def.max)
+		, count(def.count)
+		, values(def.values)
+		, index(index)
+		, value(def.values[index])
+		{}
+};]]
+end
+
 return gen

tests/interleave_arrays/attrib_data.lua

 return {
 	{size = 3,	type = "GL_FLOAT",			norm = "GL_FALSE",	ctype = "GLfloat", initVal = "1.0f", name = "positions"},
 	{size = 4,	type = "GL_UNSIGNED_BYTE",	norm = "GL_TRUE",	ctype = "GLubyte", initVal = "255", name = "color"},
-	{size = 2,	type = "GL_SHORT",			norm = "GL_FALSE",	ctype = "GLshort", initVal = "0f", name = "texCoord"},
+	{size = 2,	type = "GL_SHORT",			norm = "GL_FALSE",	ctype = "GLshort", initVal = "0", name = "texCoord"},
 	{size = 3,	type = "GL_FLOAT",			norm = "GL_FALSE",	ctype = "GLfloat", initVal = "1.0f", name = "normal"},
 	{size = 3,	type = "GL_FLOAT",			norm = "GL_FALSE",	ctype = "GLfloat", initVal = "1.0f", name = "tangent"},
 	{size = 3,	type = "GL_FLOAT",			norm = "GL_FALSE",	ctype = "GLfloat", initVal = "1.0f", name = "bitangent"},

tests/interleave_arrays/suite.lua

 		std::cout << e.what() << std::endl;
 		throw;
 	}
-}
-]]
+}]]
 
 test "arrayIndivSep"
 	desc "Separate arrays, where each array is within its own buffer object."
 	
 	flags {"finish", "swap"}
 	render_flags {"discard"}
+	
+	variables {
+		vaos = "gl list vao",
+	}
+	
+	init [[
+vaos = util::CreateVertexArrays($attribute_count.count);
+BOOST_FOREACH(int numAttribs, $attribute_count.range())
+{
+	glBindVertexArray(vaos[numAttribs - $attribute_count.min]);
+	for(int attrib = 0; attrib < numAttribs; ++attrib)
+	{
+		glEnableVertexAttribArray(attrib);
+		glBindBuffer(GL_ARRAY_BUFFER, suite.separateArrayBuffers[attrib]);
+		glVertexAttribPointer(
+			attrib,
+			suite.attribSize[attrib],
+			suite.attribType[attrib],
+			suite.attribNormalized[attrib],
+			0,
+			0);
+	}
+}
 
+glBindVertexArray(0);
+]]
+
+	execinit [[
+glBindVertexArray(vaos[$attribute_count.index]);
+glUseProgram(suite.programs[$attribute_count.index]);
+]]
+
+	exec [[glDrawArrays(GL_POINTS, 0, $vertex_count.value);]]
+
+
+	execfinal [[
+glBindVertexArray(0);
+glUseProgram(0);
+]]
+

tests/premake4.lua

 dofile "../glsdk/links.lua"
 local codegen = require "codegen"
 
+--[[
 solution "perftests"
 	configurations { "Debug", "Release" }
 
 
 	configuration "linux"
 		links {"GL", "GLU"}
+]]
 
 local matches = os.matchfiles("**suite.lua")
 
 end
 
 codegen.gencode()
+--codegen.genproj()