Beispiel #1
0
bool RelaxNGValidator::LoadGrammar(const std::string& grammar)
{
	TIMER_ACCRUE(xml_validation);

	shared_ptr<RelaxNGSchema> schema;

	{
		CScopeLock lock(g_SchemaCacheLock);
		std::map<std::string, shared_ptr<RelaxNGSchema> >::iterator it = g_SchemaCache.find(grammar);
		if (it == g_SchemaCache.end())
		{
			schema = shared_ptr<RelaxNGSchema>(new RelaxNGSchema(grammar));
			g_SchemaCache[grammar] = schema;
		}
		else
		{
			schema = it->second;
		}
	}

	m_Schema = schema->m_Schema;

	if (!m_Schema)
		return false;
	return true;
}
Beispiel #2
0
CShaderManager::CShaderManager()
{
#if USE_SHADER_XML_VALIDATION
    {
        TIMER_ACCRUE(tc_ShaderValidation);
        CVFSFile grammar;
        if (grammar.Load(g_VFS, L"shaders/program.rng") != PSRETURN_OK)
            LOGERROR("Failed to read grammar shaders/program.rng");
        else
        {
            if (!m_Validator.LoadGrammar(grammar.GetAsString()))
                LOGERROR("Failed to load grammar shaders/program.rng");
        }
    }
#endif

    // Allow hotloading of textures
    RegisterFileReloadFunc(ReloadChangedFileCB, this);
}
Beispiel #3
0
bool RelaxNGValidator::ValidateEncoded(const std::wstring& filename, const std::string& document) const
{
	TIMER_ACCRUE(xml_validation);

	if (!m_Schema)
	{
		LOGERROR("RelaxNGValidator: No grammar loaded");
		return false;
	}

	xmlDocPtr doc = xmlReadMemory(document.c_str(), (int)document.size(), utf8_from_wstring(filename).c_str(), NULL, XML_PARSE_NONET);
	if (doc == NULL)
	{
		LOGERROR("RelaxNGValidator: Failed to parse document '%s'", utf8_from_wstring(filename).c_str());
		return false;
	}

	bool ret = ValidateEncoded(doc);
	xmlFreeDoc(doc);
	return ret;
}
Beispiel #4
0
	bool Compile(GLhandleARB shader, const VfsPath& file, const CStr& code)
	{
		TIMER_ACCRUE(tc_ShaderGLSLCompile);

		ogl_WarnIfError();

		const char* code_string = code.c_str();
		GLint code_length = code.length();
		pglShaderSourceARB(shader, 1, &code_string, &code_length);

		pglCompileShaderARB(shader);

		GLint ok = 0;
		pglGetShaderiv(shader, GL_COMPILE_STATUS, &ok);

		GLint length = 0;
		pglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);

		// Apparently sometimes GL_INFO_LOG_LENGTH is incorrectly reported as 0
		// (http://code.google.com/p/android/issues/detail?id=9953)
		if (!ok && length == 0)
			length = 4096;

		if (length > 1)
		{
			char* infolog = new char[length];
			pglGetShaderInfoLog(shader, length, NULL, infolog);

			if (ok)
				LOGMESSAGE(L"Info when compiling shader '%ls':\n%hs", file.string().c_str(), infolog);
			else
				LOGERROR(L"Failed to compile shader '%ls':\n%hs", file.string().c_str(), infolog);

			delete[] infolog;
		}

		ogl_WarnIfError();

		return (ok ? true : false);
	}
Beispiel #5
0
bool RelaxNGValidator::ValidateEncoded(const std::wstring& filename, const std::string& document)
{
	TIMER_ACCRUE(xml_validation);

	if (!m_Schema)
	{
		LOGERROR(L"RelaxNGValidator: No grammar loaded");
		return false;
	}

	xmlDocPtr doc = xmlReadMemory(document.c_str(), (int)document.size(), utf8_from_wstring(filename).c_str(), NULL, XML_PARSE_NONET);
	if (doc == NULL)
	{
		LOGERROR(L"RelaxNGValidator: Failed to parse document");
		return false;
	}

	xmlRelaxNGValidCtxtPtr ctxt = xmlRelaxNGNewValidCtxt(m_Schema);
	int ret = xmlRelaxNGValidateDoc(ctxt, doc);
	xmlRelaxNGFreeValidCtxt(ctxt);
	xmlFreeDoc(doc);

	if (ret == 0)
	{
		return true;
	}
	else if (ret > 0)
	{
		LOGERROR(L"RelaxNGValidator: Validation failed");
		return false;
	}
	else
	{
		LOGERROR(L"RelaxNGValidator: Internal error %d", ret);
		return false;
	}
}
Beispiel #6
0
void* pool_alloc(Pool* p, size_t size)
{
	TIMER_ACCRUE(tc_pool_alloc);
	// if pool allows variable sizes, go with the size parameter,
	// otherwise the pool el_size setting.
	const size_t el_size = p->el_size? p->el_size : Align<allocationAlignment>(size);
	ASSERT(el_size != 0);

	// note: freelist is always empty in pools with variable-sized elements
	// because they disallow pool_free.
	void* el = mem_freelist_Detach(p->freelist);
	if(!el)	// freelist empty, need to allocate a new entry
	{
		// expand, if necessary
		if(da_reserve(&p->da, el_size) < 0)
			return 0;

		el = p->da.base + p->da.pos;
		p->da.pos += el_size;
	}

	ASSERT(pool_contains(p, el));	// paranoia
	return el;
}
Beispiel #7
0
bool CShaderManager::NewProgram(const char* name, const CShaderDefines& baseDefines, CShaderProgramPtr& program)
{
    PROFILE2("loading shader");
    PROFILE2_ATTR("name: %s", name);

    if (strncmp(name, "fixed:", 6) == 0)
    {
        program = CShaderProgramPtr(CShaderProgram::ConstructFFP(name+6, baseDefines));
        if (!program)
            return false;
        program->Reload();
        return true;
    }

    VfsPath xmlFilename = L"shaders/" + wstring_from_utf8(name) + L".xml";

    CXeromyces XeroFile;
    PSRETURN ret = XeroFile.Load(g_VFS, xmlFilename);
    if (ret != PSRETURN_OK)
        return false;

#if USE_SHADER_XML_VALIDATION
    {
        TIMER_ACCRUE(tc_ShaderValidation);

        // Serialize the XMB data and pass it to the validator
        XML_Start();
        XML_SetPrettyPrint(false);
        XML_WriteXMB(XeroFile);
        bool ok = m_Validator.ValidateEncoded(wstring_from_utf8(name), XML_GetOutput());
        if (!ok)
            return false;
    }
#endif

    // Define all the elements and attributes used in the XML file
#define EL(x) int el_##x = XeroFile.GetElementID(#x)
#define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
    EL(attrib);
    EL(define);
    EL(fragment);
    EL(stream);
    EL(uniform);
    EL(vertex);
    AT(file);
    AT(if);
    AT(loc);
    AT(name);
    AT(semantics);
    AT(type);
    AT(value);
#undef AT
#undef EL

    CPreprocessorWrapper preprocessor;
    preprocessor.AddDefines(baseDefines);

    XMBElement Root = XeroFile.GetRoot();

    bool isGLSL = (Root.GetAttributes().GetNamedItem(at_type) == "glsl");
    VfsPath vertexFile;
    VfsPath fragmentFile;
    CShaderDefines defines = baseDefines;
    std::map<CStrIntern, int> vertexUniforms;
    std::map<CStrIntern, CShaderProgram::frag_index_pair_t> fragmentUniforms;
    std::map<CStrIntern, int> vertexAttribs;
    int streamFlags = 0;

    XERO_ITER_EL(Root, Child)
    {
        if (Child.GetNodeName() == el_define)
        {
            defines.Add(CStrIntern(Child.GetAttributes().GetNamedItem(at_name)), CStrIntern(Child.GetAttributes().GetNamedItem(at_value)));
        }
        else if (Child.GetNodeName() == el_vertex)
        {
            vertexFile = L"shaders/" + Child.GetAttributes().GetNamedItem(at_file).FromUTF8();

            XERO_ITER_EL(Child, Param)
            {
                XMBAttributeList Attrs = Param.GetAttributes();

                CStr cond = Attrs.GetNamedItem(at_if);
                if (!cond.empty() && !preprocessor.TestConditional(cond))
                    continue;

                if (Param.GetNodeName() == el_uniform)
                {
                    vertexUniforms[CStrIntern(Attrs.GetNamedItem(at_name))] = Attrs.GetNamedItem(at_loc).ToInt();
                }
                else if (Param.GetNodeName() == el_stream)
                {
                    CStr StreamName = Attrs.GetNamedItem(at_name);
                    if (StreamName == "pos")
                        streamFlags |= STREAM_POS;
                    else if (StreamName == "normal")
                        streamFlags |= STREAM_NORMAL;
                    else if (StreamName == "color")
                        streamFlags |= STREAM_COLOR;
                    else if (StreamName == "uv0")
                        streamFlags |= STREAM_UV0;
                    else if (StreamName == "uv1")
                        streamFlags |= STREAM_UV1;
                    else if (StreamName == "uv2")
                        streamFlags |= STREAM_UV2;
                    else if (StreamName == "uv3")
                        streamFlags |= STREAM_UV3;
                }
                else if (Param.GetNodeName() == el_attrib)
                {
                    int attribLoc = ParseAttribSemantics(Attrs.GetNamedItem(at_semantics));
                    vertexAttribs[CStrIntern(Attrs.GetNamedItem(at_name))] = attribLoc;
                }
            }
        }
Beispiel #8
0
bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& baseDefines, CShaderProgramPtr& program)
{
	if (strncmp(name, "fixed:", 6) == 0)
	{
		program = CShaderProgramPtr(CShaderProgram::ConstructFFP(name+6));
		if (!program)
			return false;
		program->Reload();
		return true;
	}

	VfsPath xmlFilename = L"shaders/" + wstring_from_utf8(name) + L".xml";

	CXeromyces XeroFile;
	PSRETURN ret = XeroFile.Load(g_VFS, xmlFilename);
	if (ret != PSRETURN_OK)
		return false;

#if USE_SHADER_XML_VALIDATION
	{
		TIMER_ACCRUE(tc_ShaderValidation);

		// Serialize the XMB data and pass it to the validator
		XML_Start();
		XML_SetPrettyPrint(false);
		XML_WriteXMB(XeroFile);
		bool ok = m_Validator.ValidateEncoded(wstring_from_utf8(name), XML_GetOutput());
		if (!ok)
			return false;
	}
#endif

	// Define all the elements and attributes used in the XML file
#define EL(x) int el_##x = XeroFile.GetElementID(#x)
#define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
	EL(vertex);
	EL(fragment);
	EL(define);
	EL(uniform);
	EL(attrib);
	EL(stream);
	AT(type);
	AT(file);
	AT(name);
	AT(value);
	AT(loc);
#undef AT
#undef EL

	XMBElement Root = XeroFile.GetRoot();

	bool isGLSL = (Root.GetAttributes().GetNamedItem(at_type) == "glsl");
	VfsPath vertexFile;
	VfsPath fragmentFile;
	std::map<CStr, CStr> defines = baseDefines;
	std::map<CStr, int> vertexUniforms;
	std::map<CStr, int> fragmentUniforms;
	int streamFlags = 0;

	XERO_ITER_EL(Root, Child)
	{
		if (Child.GetNodeName() == el_define)
		{
			defines[Child.GetAttributes().GetNamedItem(at_name)] = Child.GetAttributes().GetNamedItem(at_value);
		}
		else if (Child.GetNodeName() == el_vertex)
		{
			vertexFile = L"shaders/" + Child.GetAttributes().GetNamedItem(at_file).FromUTF8();

			XERO_ITER_EL(Child, Param)
			{
				if (Param.GetNodeName() == el_uniform)
				{
					vertexUniforms[Param.GetAttributes().GetNamedItem(at_name)] = Param.GetAttributes().GetNamedItem(at_loc).ToInt();
				}
				else if (Param.GetNodeName() == el_stream)
				{
					CStr StreamName = Param.GetAttributes().GetNamedItem(at_name);
					if (StreamName == "pos")
						streamFlags |= STREAM_POS;
					else if (StreamName == "normal")
						streamFlags |= STREAM_NORMAL;
					else if (StreamName == "color")
						streamFlags |= STREAM_COLOR;
					else if (StreamName == "uv0")
						streamFlags |= STREAM_UV0;
					else if (StreamName == "uv1")
						streamFlags |= STREAM_UV1;
					else if (StreamName == "uv2")
						streamFlags |= STREAM_UV2;
					else if (StreamName == "uv3")
						streamFlags |= STREAM_UV3;
				}
				else if (Param.GetNodeName() == el_attrib)
				{
					// TODO: add support for vertex attributes
				}
			}
		}
		else if (Child.GetNodeName() == el_fragment)
Beispiel #9
0
	bool Link()
	{
		TIMER_ACCRUE(tc_ShaderGLSLLink);

		ENSURE(!m_Program);
		m_Program = pglCreateProgramObjectARB();

		pglAttachObjectARB(m_Program, m_VertexShader);
		ogl_WarnIfError();
		pglAttachObjectARB(m_Program, m_FragmentShader);
		ogl_WarnIfError();

		// Set up the attribute bindings explicitly, since apparently drivers
		// don't always pick the most efficient bindings automatically,
		// and also this lets us hardcode indexes into VertexPointer etc
		for (std::map<CStrIntern, int>::iterator it = m_VertexAttribs.begin(); it != m_VertexAttribs.end(); ++it)
			pglBindAttribLocationARB(m_Program, it->second, it->first.c_str());

		pglLinkProgramARB(m_Program);

		GLint ok = 0;
		pglGetProgramiv(m_Program, GL_LINK_STATUS, &ok);

		GLint length = 0;
		pglGetProgramiv(m_Program, GL_INFO_LOG_LENGTH, &length);

		if (!ok && length == 0)
			length = 4096;

		if (length > 1)
		{
			char* infolog = new char[length];
			pglGetProgramInfoLog(m_Program, length, NULL, infolog);

			if (ok)
				LOGMESSAGE(L"Info when linking program '%ls'+'%ls':\n%hs", m_VertexFile.string().c_str(), m_FragmentFile.string().c_str(), infolog);
			else
				LOGERROR(L"Failed to link program '%ls'+'%ls':\n%hs", m_VertexFile.string().c_str(), m_FragmentFile.string().c_str(), infolog);
			
			delete[] infolog;
		}

		ogl_WarnIfError();

		if (!ok)
			return false;

		m_Uniforms.clear();
		m_Samplers.clear();

		Bind();

		ogl_WarnIfError();

		GLint numUniforms = 0;
		pglGetProgramiv(m_Program, GL_ACTIVE_UNIFORMS, &numUniforms);
		ogl_WarnIfError();
		for (GLint i = 0; i < numUniforms; ++i)
		{
			char name[256] = {0};
			GLsizei nameLength = 0;
			GLint size = 0;
			GLenum type = 0;
			pglGetActiveUniformARB(m_Program, i, ARRAY_SIZE(name), &nameLength, &size, &type, name);
			ogl_WarnIfError();

			GLint loc = pglGetUniformLocationARB(m_Program, name);

			CStrIntern nameIntern(name);
			m_Uniforms[nameIntern] = std::make_pair(loc, type);

			// Assign sampler uniforms to sequential texture units
			if (type == GL_SAMPLER_2D
			 || type == GL_SAMPLER_CUBE
#if !CONFIG2_GLES
			 || type == GL_SAMPLER_2D_SHADOW
#endif
			)
			{
				int unit = (int)m_Samplers.size();
				m_Samplers[nameIntern].first = (type == GL_SAMPLER_CUBE ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D);
				m_Samplers[nameIntern].second = unit;
				pglUniform1iARB(loc, unit); // link uniform to unit
				ogl_WarnIfError();
			}
		}

		// TODO: verify that we're not using more samplers than is supported

		Unbind();

		ogl_WarnIfError();

		return true;
	}